Дифференциальный тест может быть приемлем в качестве юнит-тестов, особенно если вы используете тестовые данные, которые используются совместно юнит-тестами.
Если вы не знаете, сколько предметов в SUT, вы можете использовать следующее:
int itemsBeforeTest = SUT.Items.Count;
SUT.AddItem();
Assert.AreEqual(itemsBeforeTest + 1, SUT.Items.Count);
Если для модульных тестов требуется так много данных, что их необходимо прочитать из большого XML-файла, это не настоящий модульный тест. Модульный тест должен проверить класс в полной изоляции и смоделировать все зависимости.
Использование шаблона, подобного шаблону Builder , также может помочь в создании тестовых данных для вашего модульного теста. Самая большая проблема с тем, что ваши тестовые данные находятся в отдельном файле, заключается в том, что трудно понять, что именно делает тест. Если вы создадите свои тестовые данные в части аранжировки вашего модульного теста, сразу станет ясно, что важно для вашего теста.
Например, допустим, у вас есть следующий код заказа для проверки правильности цены счета:
Address billingAddress = new Address("Stationsweg 9F",
"Groningen", "Nederland", "9726AE"); shippingAddress = new Address("Aweg 1",
"Groningen", "Nederland", "9726AB");
Customer customer = new Customer(99, "Piet", "Klaassens",
30,
billingAddress,
shippingAddress);
Product product = new Product(88, "Tafel", 19.99);
Invoice invoice = new Invoice(customer);
Может быть изменено на следующее при использовании Builder
Invoice invoice = Builder<Invoice>.CreateNew()
.With(i => i.Product = Builder<Product>.CreateNew()
.With(p => p.Price = 19.99)
.Build())
.Build();
При использовании Builder гораздо проще увидеть, что важно, и ваш код также более удобен в обслуживании.
Рефакторинг кода, чтобы стать более тестируемым - это широкая тема. Все сводится к размышлению о том, «как бы я протестировал этот код?» пока вы пишете код.
Возьмите следующий пример:
public class AlarmClock
{
public AlarmClock()
{
SatelliteSyncService = new SatelliteSyncService();
HardwareClient = new HardwareClient();
}
}
Это сложно проверить. При тестировании AlarmClock необходимо убедиться, что SatteliteSyncService и HardwareClient работают нормально.
Это изменение в конструкторе облегчает тестирование:
public AlarmClock(IHardwareClient hardwareClient, ISatelliteSyncService satelliteSyncService)
{
SatelliteSyncService = satelliteSyncService;
HardwareClient = hardwareClient;
}
Такие методы, как Внедрение зависимостей помогают сделать рефакторинг вашего кода более удобным для тестирования. Также следите за статическими значениями, такими как DateTime.Now или использование Singleton, потому что их сложно проверить.
Действительно хорошее введение в написание тестируемого кода можно найти здесь .