简体   繁体   English

使用代码主体中声明的具体类的单元测试类

[英]unit testing classes that use concrete classes declared in code body

Very simply what I'm trying to find out is, is there any way of cleanly unit testing this body of code?很简单,我想找出的是,有没有办法对这段代码进行干净的单元测试? I can instantiate it and run some assertions but I mean actual unit testing where i would mock the service object to remove any dependancies of the class under test and actually have it test only this class and not its dependent services (in this case ConcreteService).我可以实例化它并运行一些断言,但我的意思是实际的单元测试,我将模拟服务 object 以删除正在测试的 class 的任何依赖关系,实际上让它只测试这个 class 的服务(而不是它的依赖服务)。

public class Foo{

    public SomeResult DoSomething(){
        var service = new ConcreteService();
        var foo = service.Execute();
        return foo;
    }

}

My normal approach is to not have this type of object creation in my body of code, but given a scenraio where this cant be changed, what are my options for unit testing it?我的正常方法是不在我的代码体中创建这种类型的 object,但是鉴于无法更改的情况,我有哪些单元测试选项?

Given the constraint (that you can't modify/recompile that code ), I'm afraid there is not much you can do apart from "integration testing" it - real dependencies, slow tests.鉴于约束(您无法修改/重新编译该代码),恐怕除了“集成测试”之外您无能为力 - 真正的依赖关系,缓慢的测试。

Instantiating a dependency within the method, instead of accepting it as a ctor or method argument makes things difficult.在方法中实例化一个依赖,而不是接受它作为一个 ctor 或方法参数会使事情变得困难。

As Ethan says, there is Moles (but to me personally it just doesn't seem right).正如 Ethan 所说,有痣(但对我个人而言,它似乎并不正确)。 I'd prefer a design change than a framework that helps me mask design issues.我更喜欢设计更改,而不是帮助我掩盖设计问题的框架。

If service.Execute() is virtual, then most mocking frameworks support this.如果 service.Execute() 是虚拟的,那么大多数 mocking 框架都支持这一点。 I personally use Rhino.Mocks .我个人使用Rhino.Mocks

See this question which details the capabilities of using Mocking frameworks on non-Interfaces and discusses the capabilities of mocking frameworks to intercept virtual calls.请参阅此问题,其中详细介绍了在非接口上使用 Mocking 框架的功能,并讨论了 mocking 框架拦截虚拟调用的功能。

If it is not virtual, and you can't change it then you can use Moles .如果它不是虚拟的,并且您无法更改它,那么您可以使用Moles The above mentioned post also mentions the ability to use TypeMock, which I personally haven't used.上面提到的帖子还提到了使用TypeMock的能力,我个人没有使用过。

The description of Moles on the Microsoft Research Site:微软研究网站上对 Moles 的描述:

Moles is a lightweight framework for test stubs and detours in .NET that is based on delegates. Moles 是一个轻量级的框架,用于在 .NET 中基于委托的测试存根和弯路。 Moles may be used to detour any .NET method, including non-virtual/static methods in sealed types. Moles 可用于绕过任何 .NET 方法,包括密封类型中的非虚拟/静态方法。

I know you mentioned that this would be an example of a situation that you couldn't change, but I would fight to refactor the class so that ConcreteService can be injected as a dependency.我知道您提到这将是您无法更改的情况的一个示例,但我会努力重构 class 以便可以将 ConcreteService 作为依赖项注入。 Refactoring is a much simpler approach to trying to work around a bad design.重构是尝试解决糟糕设计的一种更简单的方法。 From what you've posted, I see no reason why you wouldn't be able to do this.从您发布的内容来看,我认为您没有理由不能这样做。

EDIT: FWIW, I agree with @Gishu.编辑: FWIW,我同意@Gishu。 If you absolutely cannot modify the class, eg you don't own it and you don't have the ability to modify it, then integration tests are the best way to do it.如果您绝对不能修改 class,例如您不拥有它并且您没有能力修改它,那么集成测试是最好的方法。 However, if you can see the code and what it's doing, I stand by what I said earlier in that there's really no reason why you shouldn't refactor.然而,如果你能看到代码和它在做什么,我支持我之前所说的,你没有理由不重构。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM