Як можна використовувати контейнер IoC для тестування одиниць? Чи корисно керувати макетами у величезному рішенні (50+ проектів) за допомогою IoC? Будь-який досвід? Будь-які бібліотеки C #, які добре працюють для її використання в одиничних тестах?
Як можна використовувати контейнер IoC для тестування одиниць? Чи корисно керувати макетами у величезному рішенні (50+ проектів) за допомогою IoC? Будь-який досвід? Будь-які бібліотеки C #, які добре працюють для її використання в одиничних тестах?
Відповіді:
Взагалі кажучи, контейнер DI не повинен бути необхідним для тестування одиниць, оскільки тестування блоку - це все, що стосується розділення обов'язків.
Розглянемо клас, який використовує інжекцію конструктора
public MyClass(IMyDependency dep) { }
У всій вашій програмі може статися, що за цим схований величезний графік залежності IMyDependency
, але в одиничному тесті ви все це згладжуєте до одного тестового подвійного .
Ви можете використовувати динамічні макети на зразок Moq або RhinoMocks для створення тестового подвійного, але це не потрібно.
var dep = new Mock<IMyDependency>().Object;
var sut = new MyClass(dep);
У деяких випадках може бути приємно мати контейнер для автоматичного перегляду, але вам не потрібно використовувати той самий контейнер DI, який використовує виробнича програма.
Як можна використовувати контейнер Ioc для тестування одиниць?
IoC буде застосовувати парадигми програмування, які полегшать тестування одиниці в ізоляції (тобто з використанням макетів): використання інтерфейсів, відсутність нових (), без одиночних клавіш ...
Але використання контейнера IoC для тестування насправді не є вимогою, воно просто забезпечить деякі засоби, наприклад, ін'єкцію макетів, але ви можете це зробити вручну.
Чи корисно керувати макетами у величезному рішенні (50+ проектів) за допомогою IoC?
Я не впевнений, що ви маєте на увазі під керуванням макетами за допомогою IoC. У будь-якому випадку контейнери IoC зазвичай можуть робити більше, ніж просто вводити макети, коли справа стосується тестування. І якщо у вас є гідна підтримка IDE, яка робить можливим рефакторинг, чому б не використовувати його?
Будь-який досвід?
Так, для величезного рішення вам як ніколи потрібне рішення, не схильне до помилок та несприятливе для рефакторингу (тобто через безпечний контейнер IoC типу або хорошу підтримку IDE).
Я часто використовую контейнер IoC у своїх тестах. Зрозуміло, вони не є "одиничними тестами" в чистому сенсі. IMO Вони більш BDDish та полегшують рефакторинг. Тести існують, щоб дати вам впевненість рефактору. Погано написані тести можуть бути як заливка цементу у ваш код.
Розглянемо наступне:
[TestFixture]
public class ImageGalleryFixture : ContainerWiredFixture
{
[Test]
public void Should_save_image()
{
container.ConfigureMockFor<IFileRepository>()
.Setup(r => r.Create(It.IsAny<IFile>()))
.Verifiable();
AddToGallery(new RequestWithRealFile());
container.VerifyMockFor<IFileRepository>();
}
private void AddToGallery(AddBusinessImage request)
{
container.Resolve<BusinessPublisher>().Consume(request);
}
}
При додаванні зображення до галереї відбувається кілька речей. Зображення змінюється за розміром, створюється ескіз, а файли зберігаються на AmazonS3. Використовуючи контейнер, я можу легше виділити лише поведінку, яку я хочу перевірити, що в цьому випадку є складовою частиною.
Автомобільне розширення контейнера стане в нагоді при використанні цієї техніки: http://www.agileatwork.com/auto-mocking-unity-container-extension/
Використання контейнерів з можливістю дозвіл незареєстрованими / Невідомими послугами , такими як SimpleInjector , DryIoc (його шахта) може повертати знущається для ще не реалізованих інтерфейсів.
Це означає, що ви можете почати розробку, використовуючи першу просту реалізацію та її знущаються залежності, і замінювати їх справжніми речами в процесі просування.