Модульный тест с Ninject Instantiate
Я пытаюсь протестировать свой сервис с помощью ninject и проекта модульного тестирования с Visual Studio 2012. Мой инжект работает нормально на моих контроллерах, но когда я пытаюсь сделать то же самое в классе модульного тестирования, я получаю Exception
,
System.NullReferenceException: Object reference not set to an instance of an object.
namespace Trex.UnitTests
{
[TestClass]
public class GiftServiceTests
{
private IGiftService _giftService;
public void GiftServiceTest(IGiftService giftService)
{
_giftService = giftService;
}
[TestMethod]
public void AddGift()
{
var list = _gift.FindAll(); <--- this line throw an exception
}
}
}
Я думаю, что что-то не так с инъекцией, но я не понимаю.
3 ответа
Это выглядит как опечатка _giftService
, Кроме того, атрибут [TestInitialize]
должен быть использован в вашем конструкторе.
Попробуйте следующий код, указав правильное имя службы _giftService, которое вместо этого вводит ваш код:
var list = __giftService.FindAll();
Изменить: модульное тестирование должно быть сделано без Ninject. Просто создайте экземпляр тестируемого объекта и вставьте макет для каждой зависимости вручную.
Вот образец с [TestInitialize]
:
Модульный тест должен иметь конструктор по умолчанию:
[TestClass]
public class TestControllersHomeController
{
private HomeController _sut;
[TestInitialize]
public void MyTestInitialize()
{
var kernel = NinjectWebCommon.CreatePublicKernel();
_sut = kernel.Resolve<HomeController>();
}
[TestMethod]
public void TestIndex()
{
var result = _sut.Index();
Assert.IsNotNull(result);
}
}
Единственный способ внедрения зависимостей в состоянии вызвать ваш конструктор и заполнить его параметром, который имеет значение, это если ядро внедрения зависимостей является тем, которое создает экземпляр вашего класса.
В вашем случае MSTest создает экземпляр вашего тестового класса, поэтому у Ninject нет шансов вызвать ваш конструктор.
Если честно, вы идете по этому поводу неправильно. Вы будете сражаться с MSTest, если продолжите это, пытаясь заставить Ninject (или любую другую инфраструктуру DI) создавать экземпляры ваших тестовых классов.
Я бы порекомендовал вам использовать 'new' для создания экземпляра тестируемого класса (_giftService = new GiftService();
). Если у этого класса есть зависимости в его конструкторе, используйте макетную среду для передачи имитированной версии этих зависимостей. Таким образом вы изолируете свои модульные тесты только от функциональности тестируемого класса.
_gift
является null
, Ваша переменная _giftService
, Вы также должны использовать [TestInitialize]
атрибут для вашего конструктора.
Дополнительный совет:
Вы не должны создавать никаких зависимостей в своем модульном тесте. Итак giftService
который вы хотите использовать, должен быть макетом или заглушкой.