很简单,我想要找到的是,有没有什么方法可以干净地单元测试这段代码?我可以实例化它并运行一些断言,但我的意思是实际的单元测试,我将模拟服务对象以删除被测试类的任何依赖性,并实际上只测试此类而不是其依赖服务(在本例中为ConcreteService)。
public class Foo{
public SomeResult DoSomething(){
var service = new ConcreteService();
var foo = service.Execute();
return foo;
}
}
我的常规方法是在我的代码体中没有这种类型的对象创建,但是如果不能更改这个类型的场景,我可以选择单元测试它吗?
答案 0 :(得分:4)
考虑到约束(你无法修改/重新编译该代码),我担心除了“集成测试”之外你没有太多可以做的 - 真正的依赖,慢速测试。
在方法中实例化依赖项,而不是将其作为ctor或方法参数接受会使事情变得困难。
正如Ethan所说,有Moles(但对我个人来说,这似乎并不正确)。我更喜欢设计变更,而不是帮助我掩盖设计问题的框架。
答案 1 :(得分:1)
如果service.Execute()是虚拟的,那么大多数模拟框架都支持这一点。我个人使用Rhino.Mocks。
请参阅this question,其中详细介绍了在非接口上使用Mocking框架的功能,并讨论了模拟框架拦截虚拟调用的功能。
如果它不是虚拟的,您无法更改它,那么您可以使用Moles。上面提到的帖子还提到了使用TypeMock的能力,我个人没有使用过。
Microsoft研究站点上的Moles说明:
Moles是.NET中基于委托的测试存根和绕道的轻量级框架。 Moles可用于绕过任何.NET方法,包括密封类型中的非虚拟/静态方法。
答案 2 :(得分:1)
我知道你提到过这将是一个你无法改变的情况的例子,但我会努力重构这个类,以便可以将ConcreteService作为依赖注入。重构是一种更简单的方法来尝试解决一个糟糕的设计。根据您发布的内容,我认为没有理由说您无法做到这一点。
编辑: FWIW,我同意@Gishu。如果您绝对无法修改该类,例如你不拥有它并且你没有能力修改它,那么集成测试是最好的方法。但是,如果你能看到代码及其正在做的事情,我会坚持我之前所说的,你没有理由不重构。