Нещодавно я прочитав статтю, в якій говорилося, що знущаються над об'єктами часто неправильно розуміють і не використовують. Чи є чіткі глузуючі анти-шаблони, на які я можу звернути увагу?
Нещодавно я прочитав статтю, в якій говорилося, що знущаються над об'єктами часто неправильно розуміють і не використовують. Чи є чіткі глузуючі анти-шаблони, на які я можу звернути увагу?
Відповіді:
Мені не подобається бачити прості бетонні заняття. Для прикладу візьмемо такий простий клас, який не залежить ні від чого іншого:
public class Person
{
private readonly string _firstName;
private readonly string _surname;
public Person(string firstName, string surname)
{
if (String.IsNullOrEmpty(firstName))
{
throw new ArgumentException("Must have first name");
}
if (String.IsNullOrEmpty(surname))
{
throw new ArgumentException("Must have a surname");
}
_firstName = firstName;
_surname = surname;
}
public string Name
{
get
{
return _firstName + " " + _surname;
}
}
}
У будь-яких тестах, що стосуються цього класу, я, скоріше, справжній був примірник і використовувався, а не якийсь інтерфейс, як-от "IPerson", витягувався, знущався з використовуваного та очікування, встановлені на. Використовуючи справжній тест, ваш тест є більш реалістичним (у вас є перевірка параметрів і реальна реалізація властивості "Ім'я"). Для такого простого класу ви не робите тести повільнішими, менш детермінованими або заплутаними логікою (вам, ймовірно, не потрібно знати, що ім'я викликали під час тестування якогось іншого класу) - які є звичайними причинами глузування / заїдання.
Як доповнення до цього, я також бачив, як люди пишуть тести, де макет встановлюється з очікуванням, тоді макет викликається безпосередньо в тесті. Ненадійно тест завжди пройде ... хммм ...
Це може здатися очевидним, але: Не використовуйте макетні об’єкти у виробничому коді! Я бачив не один приклад, коли виробничий код залежав від характеристик певних макетних об'єктів (наприклад, MockHttpServletRequest
від Springframework).
На мою думку, це надмірна перевірка виклику методів на макетах. Я відчуваю, що це практика, яку застосовують декілька глузуючих фреймворків, таких як EasyMock, де поведінка макету за замовчуванням полягає в збої кожного разу, коли виникає додатковий виклик методу, який не був визначений раніше. Цей вид суворої перевірки методу макетів може призвести до крихких конструкцій, коли найменша зміна коду може призвести до виходу з ладу цілого набору тестів, хоча функціональність основної системи все одно однакова.
Рішенням цього є початок використання заглушок замість макетів. Стаття, яку я знайшов особливо просвічуючою темою, була знайдена в Javadoc Mockito: http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html (див. "2. Як щодо заглушки?" ), посилаючись на: http://monkeyisland.pl/2008/07/12/should-i-worry-about-the-unexpected/ .
Мені подобалося працювати з Mockito поки що, оскільки він не застосовує цієї суворої глузливої поведінки, а використовує замість цього заглушки. Він також застосовує перевірку методів на конкретних, а не на цілому макетному об'єкті; тож ви в кінцевому підсумку перевіряєте лише методи, які дійсно мають значення у вашому тестовому сценарії.
Тут і там є кілька книг, які я можу порекомендувати торкнутися цієї теми, а також глузувати і загалом:
xUnit Шаблони
Мистецтво одиничного тестування: із прикладами в .Net
Тестування Java наступного покоління: TestNG та розширені концепції (ця книга в основному стосується testNG, але є приємна глава про глузування)
Answer.RETURNS_SMART_NULLS
налаштування для глузування, що допомагає діагностувати це.
У своєму досвіді я спостерігав небагато анти-моделей.
Інакше мій досвід з глузуванням, особливо Mockito, був вітерцем. Вони зробили тести дуже просто писати та підтримувати. Тестування взаємодії перегляду GWT / презентаторів набагато простіше з макетами, ніж GWTTestCase.
Я вважаю, що тести, які використовують макети в декількох шарах програми, особливо важко розшифрувати та змінити. Однак я думаю, що це було пом’якшено в останні роки вдосконаленими API макетів (я використовую JMock там, де це зручно).
5 або 6 років тому API, як EasyMock, були потужними, але дуже громіздкими. Часто код тесту, який використовував його, був на порядок складнішим, ніж код, який він тестував. Тоді я намагався впливати на команди, в яких я працював, дуже економно використовувати це і робити з простими макетами ручної роботи, які були просто альтернативними реалізаціями інтерфейсів спеціально для тестування.
Нещодавно мої сильні думки з цього приводу стали більш м'якими, оскільки знущаються API зробили тести, які використовують їх більш читабельно. По суті, я хочу, щоб мій код (включаючи тести) мінявся іншими розробниками, не даючи їм відчути, що вони просіюють через безліч неясних дзвінків API.