Когда у вас есть контейнер IoC, надеюсь, у вас также будет происходить какое-то внедрение зависимостей - будь то через конструктор или сеттер.
Суть модульного тестирования состоит в том, чтобы тестировать компоненты изолированно, и выполнение 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");
}