Как да поддържате Mock обект в синхрон с целевия обект

Питам за управление на макетни обекти, независимо от конкретната реализация (EasyMock, Mock Object и т.н.).

Не бях склонен да използвам Mock обект в моите модулни тестове поради следната причина: поведението на Mock обект трябва да отразява поведението на обекта, който се подиграва. Ако поведението на подигравания обект се е променило, ще трябва да променим и поведението на подигравания обект. Ако не го направим, поведението на макетния обект няма да се синхронизира с реалния обект и по този начин ще направи модулното тестване безсмислено и е опасно.

Въпросът ми е как да поддържам макетния обект в синхрон с целевия обект? Как разпространявате промените? Използвате ли някаква техника за управление на фиктивни обекти?

Редактиране: Променете заглавието, за да стесните обхвата.


person janetsmith    schedule 07.03.2011    source източник


Отговори (4)


Добре дефинираните API не трябва да имат този вид свобода на действие: даден набор от входни данни, обектът, който се подиграва, трябва да се държи само по тези конкретни начини: поведението е обвързано с интерфейса. Ако има разрешена вариация, тогава вашият макет обект трябва да тества всички различни неща, които този обект може да направи.

Можете да намалите риска от отклонение в поведението чрез:

  • Интеграционно тестване и
  • Сравняване на вашите фалшиви данни с реалната реализация.
person Edward Z. Yang    schedule 07.03.2011

Не съм експерт, но моята мисъл по този въпрос е, че макетният обект е предназначен за единичен тестов случай/взаимодействие. И ако това взаимодействие се промени, вие очевидно искате това да бъде отразено във вашите тестове. Но това не трябва да прекъсва всички фалшиви обекти на клас, тъй като те проверяват за различни взаимодействия, които все още може да са валидни.

person driushkin    schedule 07.03.2011

Ако ClassA извика:

 AThing aThing = ClassB.GiveMeAThing()

ClassA никога не трябва да се интересува как ClassB получава това нещо. По този начин, мъниче -- StubB -- никога не трябва да се интересува как се държи истинската реализация на мънича. Само ако се промени самото взаимодействие - типът на връщане или извикващите аргументи - трябва да се промени StubB и това ще е необходимо, ако искате кодът ви да се компилира :-)

В случай, че вашият ClassB започне да връща нули или хвърля нови типове изключения; Е, тогава трябва да се напишат изцяло нови тестове и вероятно също нови мъничета.

Поздрави, Мортен

person Morten    schedule 07.03.2011

Вие сте на прав път. Не искате крехки тестове, които трябва да се променят всеки път, когато рефакторирате тестваната система.

Като цяло концентрирам тестовете си върху публичния интерфейс. Ако публичният ви интерфейс се промени, вероятно ще трябва да промените повече от тестове.

Също така се опитвам да правя тестване на състоянието вместо тестване на поведението, когато е възможно. Така че обикновено ще използвам прекъсвания вместо подигравки. (Повечето рамки за изолиране/подиграване ще ви позволят да създадете едно от двете.) Проверявам състоянието на системата (или класа) под тест, вместо да искам от макет обект да се самопровери.

Въпреки това се опитвам да бъда гъвкав. Ако тестването на макетно поведение има смисъл в даден случай, ще използвам това. Ако трябва да изложа вътрешни елементи, за да получа прилично покритие, ще го направя.

РЕДАКТИРАНЕ: Вижте също тази статия от Скот Бейн.

person TrueWill    schedule 07.03.2011