如何在测试中管理IoC容器?

时间:2010-05-27 17:21:54

标签: testing inversion-of-control ninject

我是测试和IoC容器的新手,有两个项目:

  • MySite.Website(MVC)
  • MySite.WebsiteTest

目前我的网站上有一个IoC容器。我应该为我的测试重新创建另一个IoC容器吗?或者有没有办法在两者中使用IoC?

2 个答案:

答案 0 :(得分:2)

当你有一个IoC容器时,希望你也会有一些依赖注入 - 无论是通过构造函数还是setter注入。

单元测试的目的是单独测试组件,并且DI在很大程度上帮助它。你想要做的是通过手动构建每个类并将其传递给所需的依赖项来对每个类进行单元测试,而不是依靠容器来构造它。

这样做很简单。您希望尽可能地隔离SUT(被测系统)。如果您的SUT依赖于另一个类和IoC来注入它,那么您实际上是在测试三个系统,而不是一个。

采用以下示例:

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);
  }
} 

ApiController构造函数是一个依赖构造函数,将在运行时由IoC容器调用。但是,在测试期间,您需要模拟IRequestParser接口并手动构建控制器。

[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");
}

答案 1 :(得分:0)

测试是关于真正的实现。所以你通常不应该在你的单元测试中使用IOC。如果您确实需要它(一个组件取决于另一个组件),使用接口隔离交互并使用模拟库(Moq很好)来模拟它并进行测试。

我认为IOC容器是测试所必需的唯一机会是集成测试。