Я считаю, что тестовый класс технически нарушает SRP, но не нарушает дух SRP.Альтернатива самопрошиванию - иметь фиктивный класс, отдельный от тестового класса.
С отдельным фиктивным классом можно подумать, что он полностью самодостаточен и удовлетворяет SRP, однако семантическая связь с классом имитацииатрибуты все еще там.Так что, на самом деле, мы не достигли никакого значимого разделения.
Взяв пример из PDF:
public class ScannerTest extends TestCase implements Display
{
public ScannerTest (String name) {
super (name);
}
public void testScan () {
// pass self as a display
Scanner scanner = new Scanner (this);
// scan calls displayItem on its display
scanner.scan ();
assertEquals (new Item (“Cornflakes”), lastItem);
}
// impl. of Display.displayItem ()
void displayItem (Item item) {
lastItem = item;
}
private Item lastItem;
}
Теперь мы создаем макет:
public class DisplayMock implements Display
{
// impl. of Display.displayItem ()
void displayItem (Item item) {
lastItem = item;
}
public Item getItem() {
return lastItem;
}
private Item lastItem;
}
public class ScannerTest extends TestCase
{
public ScannerTest (String name) {
super (name);
}
public void testScan () {
// pass self as a display
DisplayMock dispMock = new DisplayMock();
Scanner scanner = new Scanner (dispMock );
// scan calls displayItem on its display
scanner.scan ();
assertEquals (new Item (“Cornflakes”), dispMock.GetItem());
}
}
В практическом плане (ИМХО) более высокая связь TestClass
с DisplayMock
является большим злом, чем нарушение SRP для TestClass
.Кроме того, с использованием фальшивых фреймворков эта проблема полностью исчезает.
РЕДАКТИРОВАТЬ Я только что столкнулся с кратким упоминанием паттерна самосшунтирования в превосходной книге Роберта К. Мартина AgileПринципы, образцы и практики в C # .Вот фрагмент из книги:
Итак, у парня, который придумал SRP (о котором подробно говорится в той же книге), нет никаких сомнений, используя selfшунт шаблон.В свете этого я бы сказал, что при использовании этого паттерна вы достаточно защищены от ООП.