开发者

How to manage IoC containers in tests?

开发者 https://www.devze.com 2023-01-01 20:56 出处:网络
I\'m very new to testing and IoC containers and have two projects: MySite.Website (MVC) MySite.WebsiteTest

I'm very new to testing and IoC containers and have two projects:

  • MySite.Website (MVC)
  • MySite.WebsiteTest

Currently I have an IoC container in my website. Should I recreate another开发者_Go百科 IoC container for my test? Or is there a way to use the IoC in both?


When you have an IoC container, hopefully you will also have some sort of dependency injection going on - whether through constructor or setter injection.

The point of a unit test is to test components in isolation and doing DI goes a long way in aiding that. What you want to do is unit test each class by manually constructing it and passing it the required dependencies, not rely on container to construct it.

The point of doing that is simple. You want to isolate the SUT(System Under Test) as much as possible. If your SUT relies on another class and IoC to inject it, you are really testing three systems, not one.

Take the following example:

public class ApiController : ControllerBase {

  IRequestParser m_Parser;

  public ApiController(IRequestParser parser) {
    m_Parser = parser;
  }

  public ActionResult Posts(string request) {
    var postId = m_Parser.GetPostId(request);
  }
} 

The ApiController constructor is a dependency constructor and will get invoked by IoC container at runtime. During test, however, you want to mock IRequestParser interface and construct the controller manually.

[Test]
public void PostsShouldCallGetPostId() {
  //use nmock for mocking
  var requestParser = m_Mocks.NewMock<IRequestParser>();
  //Set up an expectation that Posts action calls GetPostId on IRequestParser
  Expect.Once.On(requestParser).Method("GetPostId").With("posts/12").Will(Return.Value(0));
  var controller = new ApiController(requestParser);
  controller.Posts("posts/12");
}


Testing is about real implementation. So you normally should not use IOC in your unit tests. In case you really feel needing it (one component depending on another one), using an interface to isolate the interaction and using a mocking lib (Moq is good) to mock it and do the testing.

The only chance I see IOC container is necessary for testing is in integration testing.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号