c# - 我是否必须在单元测试中伪造一个值对象

标签 c# unit-testing dependency-injection tdd

我使用 TDD 编写了一个类,其中包含一个方法(被测方法),该方法将一个简单的值对象作为参数 (range)。

代码:

被测方法如下所示:

public List<string> In(IRange range)
{
     var result = new List<string>();
     for (int i = range.From; i <= range.To; i++)
     {
          //...
     }
     return result;
}

此外,我有一个单元测试来验证我的测试方法:

[TestMethod]
public void In_SimpleNumbers_ReturnsNumbersAsList()
{
    var range = CreateRange(1, 2);
    var expected = new List<string>() { "1", "2" };
    var result = fizzbuzz.In(range);
    CollectionAssert.AreEqual(expected, result);
}

private IRange CreateRange(int from, int to)
{
    return new Fakes.StubIRange() 
    { 
        FromGet = () => { return from; }, 
        ToGet = () => { return to; } 
    };
}

问题:

我读过 Roy Osherove 关于单元测试的书(“单元测试的艺术”)。他在那里说

"external dependencies (filesystem, time, memory etc.) should be replaced by stubs"

外部依赖是什么意思?我的值对象(范围)是否也是应该伪造的外部依赖项?我应该伪造一个类具有的所有依赖项吗?

谁能给我一个建议

最佳答案

长话短说

做最简单的事情来解决你的问题。


我使用 TDD 的时间越长,我就越欣赏务实的值(value)。编写 super 独立的单元测试本身并不是一个值(value)。这些测试可帮助您编写易于理解并解决正确问题的高质量代码。

如果您需要能够切换到另一个具体的范围实现而无需修改依赖它的代码,那么为范围类添加一个接口(interface)是一个好主意。

但是,如果您没有那个需求,添加接口(interface)没有任何实际意义,但它确实增加了一些复杂性,这实际上使您远离了编写易于理解的代码来解决问题的目标。

注意不要过多考虑 future 可能发生的变化。 YAGNI是一个很好的原则。如果您一直在进行 TDD,那么如果将来有实际需要,重构代码不会有任何问题,因为您有可靠的测试可以依赖。

一般而言,我不会将适当的值对象视为依赖项。如果它足够复杂,让您在测试时让其他代码使用它感到不舒服,那么听起来它实际上更像是一种服务。

关于c# - 我是否必须在单元测试中伪造一个值对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16337322/

相关文章:

c# - 未将对象引用设置为对象实例 - MySqlCommand

c# - 如何通过 C# 中的 Exchange Web 服务确定电子邮件的发件人?

python - 为不同的响应模拟 urllib2.urlopen().read()

python - FastAPI 异步类依赖项

c# - 通过 EntityFramework 插入默认值

c# - 服务堆栈性能

delphi - 如何模拟另一个类负责实例化的类?

php - 网 bean "no tests executed"

c# - DryIoc、LightInject 体验

android - 在整洁的架构中将依赖注入(inject)类放在哪里