单元测试工厂方法,具有作为返回类型的具体类

jpo*_*poh 33 tdd unit-testing factory

所以我有一个工厂类,我正在尝试研究单元测试应该做什么.从这个问题我可以验证返回的接口是我期望的特定具体类型.

如果工厂返回具体类型,我应该检查什么(因为目前不需要使用接口)?目前我做的事情如下:

[Test]
public void CreateSomeClassWithDependencies()
{
    // m_factory is instantiated in the SetUp method
    var someClass = m_factory.CreateSomeClassWithDependencies();

    Assert.IsNotNull(someClass);
}
Run Code Online (Sandbox Code Playgroud)

这个问题是Assert.IsNotNull看起来有点多余.

另外,我的工厂方法可能正在设置该特定类的依赖关系,如下所示:

public SomeClass CreateSomeClassWithDependencies()
{
    return new SomeClass(CreateADependency(), CreateAnotherDependency(),
                         CreateAThirdDependency());
}
Run Code Online (Sandbox Code Playgroud)

我想确保我的工厂方法正确设置所有这些依赖项.有没有其他方法可以做到这一点来制作那些public/internal我在单元测试中检查的依赖属性?(我不是修改测试对象以适应测试的忠实粉丝)

编辑:回应罗伯特哈维的问题,我正在使用NUnit作为我的单元测试框架(但我不会认为它会产生太多差异)

Mar*_*ann 34

通常,创建可用于基于状态的测试的公共属性没有任何问题.是的:这是您为启用测试场景而创建的代码,但它是否会损害您的API?是否可以想到其他客户会在以后找到相同的属性?

测试专用代码和测试驱动设计之间存在细微差别.我们不应该引入除了满足测试要求之外没有其他潜力的代码,但是引入遵循普遍接受的设计原则的新代码是非常好的.我们让测试驱动我们的设计 - 这就是我们称之为TDD的原因:)

在我看来,向一个类添加一个或多个属性以使用户更好地检查该类是一件合理的事情,所以我认为你不应该忽略引入这些属性.

除此之外,我第二个nader的答案:)

  • 有时,仅仅为了测试而公开类内部结构是不可行的.例如,您不希望意外泄漏类的正确性所依赖的内部可变对象.这可能是坏事的几个原因:(a)违反封装原则,以及(b)类安全(其他甚至恶意的代码可能会以无意和不合需要的方式改变类).当你不想泄露抽象时,你如何测试工厂? (20认同)
  • 根据您的API的使用范围,我认为推测性地添加这些方法是因为客户可能会发现它们很有用,从长远来看会导致您遇到麻烦.每次执行此操作时,您必须维护并测试该方法或执行弃用过程 - 以防客户端在某处使用该方法.这似乎需要很多成本才能获得很少的好处; 特别是如果你在整个API中持续或经常这样做.我的建议是尽可能保持您的API尽可能小 - 紧要 - 客户需要它,所以你的测试也应如此. (8认同)
  • +1“让测试驱动我们的设计”。使用属性来公开依赖关系有助于配置依赖关系并使它们显而易见。两者都是好东西。 (2认同)

Nad*_*zie 24

如果工厂正在返回具体类型,并且您保证工厂始终返回具体类型,而不是null,那么不,测试中没有太多价值.它确实允许您确保随着时间的推移不会违反此期望,并且不会抛出异常等内容.

这种测试方式可以确保在您将来进行更改时,您的工厂行为不会在您不知情的情况下发生变化.

如果您的语言支持它,那么对于依赖项,您可以使用反射.这并不总是最容易维护,并且将您的测试与您的实现紧密结合.你必须决定这是否可以接受.这种方法往往非常脆弱.

但是您似乎正在尝试分离构造哪些类,以及如何调用构造函数.使用DI框架获得这种灵活性可能会更好.

通过根据new需要添加所有类型,您不会给自己多个接缝(接缝是一个可以改变程序中的行为而无需在该位置进行编辑的地方).

通过您给出的示例,您可以从工厂派生一个类.然后覆盖/模拟CreateADependency(),CreateAnotherDependency()CreateAThirdDependency().现在,当您调用时CreateSomeClassWithDependencies(),您可以感知是否创建了正确的依赖项.

注意:"seam"的定义来自Michael Feather的书"有效地使用遗留代码".它包含许多为未经测试的代码添加可测试性的技术示例.你可能会发现它非常有用.

  • 我喜欢这个答案,如果你必须处理传统或接近遗留(.net 1.1)代码而没有测试,那本书就是神派.如果你是一个以前没有完成单元测试的团队,并且你有很多棕色地带代码,你想要进行单元测试,这本书非常有用,那也很好. (2认同)