我用它作为开始单元测试的机会,因为我认为它对我的代码有益.从那以后,我一直在阅读一本书籍,以便快速掌握JUnit和单元测试.
基本上我的问题归结为我收到的两条相互矛盾的建议:
1)静力学是邪恶的.不要碰静电.不要测试私有,你可能想要一个类.
2)使用工厂进行创建以允许使用参数进行依赖注入 – 可能允许使用模拟和存根进行隔离.
在我的例子中,我希望执行以下操作:
double height = 223.42; // this was set iterating over a collection of doubles //blah HeightBounds b = HeightBounds.getHeightBounds(height); //more blah
我这样做是为了避免构建一个非常长而复杂的代码块,我只能对其进行全面测试.这样我就可以测试公共可访问对象,以确保系统组件都能正确执行.
常识告诉我,静态工厂没有任何问题,并且它们很容易测试,但是在我学习测试驱动设计时,我是否遗漏了一些令人眼花缭乱的东西?
谢谢
解决方法
如果您将IHeightBounds实现注入到您的类中,那么您可以模拟它,以便您可以测试当您的类的依赖项执行某些操作时会发生什么.
例如,如果HeightBounds抛出异常怎么办?还是返回null?或者您想测试何时返回特定的HeightBound?使用接口可以很容易地模拟这种行为,使用静态工厂时,制作数据以在类中创建所需结果会更加困难.
您仍然可以只有一个HeightBounds实现,并且可以单独测试它,但是您可以在没有真正实现的情况下测试上面的方法.
我可能会有一个IHeightBoundFactory接口并在类中注入一个实现.
至于测试私人,通常你不想.您希望测试两件事中的一件,要么结果符合您的预期,要么交互符合您的预期.
如果你有一个名为Add的方法和一个名为GetAll的方法,那么你可能想要在调用Add时测试它,然后调用GetAll,你会得到你添加的那个.你不关心它是如何实现的,只是它有效.这是测试结果.通常在这种情况下,您希望创建返回数据的模拟对象.这似乎是你的情况.
如果在调用Add时,您希望记录正在添加的内容,那么您希望测试与日志记录依赖项的交互,因此您将注入模拟依赖项并验证在调用Add时是否发生了与该类的交互.通常在这种情况下,您希望创建具有期望设置的模拟对象,并验证是否已满足这些期望.在上面描述的情况下,它看起来不是必要的.