简体   繁体   中英

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).

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?

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.

As Ethan says, there is Moles (but to me personally it just doesn't seem right). 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. I personally use 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.

If it is not virtual, and you can't change it then you can use Moles . The above mentioned post also mentions the ability to use TypeMock, which I personally haven't used.

The description of Moles on the Microsoft Research Site:

Moles is a lightweight framework for test stubs and detours in .NET that is based on delegates. Moles may be used to detour any .NET method, including non-virtual/static methods in sealed types.

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. 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. 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. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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