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

MUG*_*G4N 7 c# tdd unit-testing dependency-injection

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

码:

测试中的方法如下所示:

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

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

[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; } 
    };
}
Run Code Online (Sandbox Code Playgroud)

题:

我读过Roy Osherove关于单元测试的书("单元测试的艺术").在那里,他说

"外部依赖项(文件系统,时间,内存等)应该由存根替换"

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

有人可以给我一个建议

Eri*_*ebo 3

长话短说

做尽可能简单的事情来解决你的问题。


我使用 TDD 的时间越长,就越体会到务实的价值。编写超级独立的单元测试本身并没有价值。这些测试可以帮助您编写易于理解并解决正确问题的高质量代码。

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

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

小心不要过多考虑未来可能发生的变化。YAGNI是一个值得遵循的好原则。如果您一直在进行 TDD,那么如果将来出现实际需要,您在重构代码时不会遇到任何问题,因为您有可靠的测试可以依赖。

一般来说,我不认为正确的值对象是依赖项。如果它足够复杂,以至于您在测试时让其他代码使用它感到不舒服,那么听起来它实际上更像是一个服务。