2010-12-09 2 views
4

Чем больше я читал макет пример, тем больше я запутаться ...Как написать единичный тест с использованием макета?

У меня есть CLASSA метод поесть(), который вызывает FatDude класса eatThemAll()

public class classA { 

    FatDude dude = new FatDude(); 

    public String eat() { 
     String result = dude.eatThemAll(); 
    } 
} 

public class FatDude { 
    public String eatThemAll() { 
     return "never full"; 
    } 
} 

Теперь я хочу, чтобы проверить CLASSA съесть (), издеваясь над классом FatDude.

public class MockFatDude extends FatDude { 
    //override 
    public String eatThemAll() { 
     return "very full"; 
    } 
} 
------------- test -------------- 
public class DoTest { 

    public void runTest() { 
     classA cl = new ClassA(); 
     String out = cl.eat(); 
     assertEqual(out, "very full"); 
    } 
} 

Этот DoTest runTest() не будет использовать класс MockFatDude, конечно. Один из способов я могу думать, чтобы изменить код, чтобы передать FatDude есть() метод ClassA как:

public class classA { 

     public String eat(FatDude dude) { 
      String result = dude.eatThemAll(); 
     } 
    } 

Затем изменить метод испытания на:

public class DoTest { 

     public void runTest() { 
      classA cl = new ClassA(); 
      String out = cl.eat(new MockFatDude()); 
      assertEqual(out, "very full"); 
     } 
    } 

Но, как вы можете видеть, я должен был изменить исходный код для удовлетворения моих потребностей. Это правильный способ? Что делать, если мне не разрешено изменять исходный код? Я знаю, если я применил концепцию TDD, это нормально изменить исходный код, но я хотел бы услышать мнение или совет, если то, что я показал выше, является правильным способом.

+0

Это java или C#? какие инструменты вы используете? Добавьте соответствующие метки. Спасибо. – 2010-12-09 08:17:35

+1

@maksymko: Я не думаю, что язык или инструменты важны для этого вопроса, кроме того, что его объектно-ориентированный язык. – 2010-12-09 08:22:10

+0

@calavera: я имел в виду это как разъяснение для более правильной классификации/фильтрации и т. Д., А не как способ помочь ответить на вопрос. – 2010-12-09 12:31:11

ответ

4

Mocking и Dependency Inversion Principle (DIP) идут рука об руку, и на большинстве языков Mocks лучше всего работает, развязывая классы с помощью интерфейсов.

В вашем случае это будет работать без необходимости изменения кода: (Изменить: я имею в виду, в будущем, если вы создадите свое приложение таким образом, вам не нужно будет менять код для издевательства зависимостей :))

  • Абстрактный интерфейс IDude
  • Конкретные классы FatDude (и MockFatDude) должен реализовать интерфейс IDude
  • обеспечивают механизм для IDude, например, чтобы быть «множество» или вводят в CLASSA - Зависимость инъекции (конструктор или получить/комплекты); или Service Locator модель лучше всего работают (чтобы заменить конкретную ClassFactory)

отметить также, что многие структуры насмешливо фактически позволяют создать Якобы конкретный класс «на лету» (см MOq и др), так что вы можете создайте функциональность MockFatDude непосредственно в своем модульном тесте.

2

Да. Вы наткнулись на какой-то хороший дизайн непосредственно из-за вашего модульного теста. Если вы посмотрите более внимательно, вы увидите, что вы удалили связь между classA и FatDude. Теперь FatDude может быть интерфейсом для поведения, которое передается при необходимости. ClassA не нужно знать, какой тип FatDude он получает, или как построить FatDude (с чизбургеры?).

Ваше решение - именно то, что я бы сделал. Нет ничего плохого в изменении кода для размещения TDD, если вы понимаете причины и преимущества/недостатки для внесения таких изменений.

Смежные вопросы