2015-10-28 9 views
0

Я пишу модульные тесты с JUnit и Mockito. Скажем, у меня есть следующий класс теста:Когда использовать, когда() в Mocktio

@Mock(name="myService") 
private myServiceClass myService; 

@InjectMocks 
private myClassIWantToTest classUnderTest; 

final myModelClass myModel = new myModelClass(); 

@Before 
private void setUp(){ 
    MockitoAnnotiations.initMocks(this); 
} 

@Test 
private void testSomething(){ 
    myModel.setCode("someCode"); 

    final MyDataClass myData = new MyDataClass(); 
    myData.setCode("someCode"); 

    doReturn("someCode").when(myModel.getCode()); 
    doReturn(myModel).when(myService.getModelByCode("someCode")); 

    assertEquals(classUnderTest.getDataByCode(eq("someCode")), myData); 
    verify(myService.getModelByCode(eq("someCode")), atLeastOnce()); 
} 

Метод getDataByCode из моих classUnderTest преобразует модель в данный и он должен иметь один и тот же код. Для меня немного расплывчато, что модульные тесты должны инкапсулировать classUnderTest из всех зависимостей. Но теперь у меня проблема. Я использую методы настройки myData и myModel для установки значения. Дело в том, что я положил DoReturn туда за myModel, но проблема в том, что это не инъецированный макет. К сожалению, метод, к которому я пытаюсь проверить, не имеет поля, он инициализирует это внутри метода, поэтому я не могу его действительно решить.

И главное, когда сеттер, например, myModel больше не работает, мой тест, как показано выше, больше не будет работать. Я думаю, у меня есть три вопроса:

  1. Насколько сложно изолировать тестовый класс? Разве мне не нужно использовать сеттеры для assertEquals?

  2. Есть ли другой способ борьбы с объектами, которые инициализируются внутри метода, который я хочу проверить? Каков наилучший способ подойти к такому вопросу?

  3. Кроме того, что было бы хорошим шаблоном для структурирования этого? В настоящее время я инициализирую свой ожидаемый результат myData внутри метода тестирования. Дело в том, что это довольно короткий и простой пример, но у меня есть классы, где у меня есть множество объектов и методов.

ответ

1

Похоже, ваша главная проблема - это дизайн класса, который вы хотите проверить. Но еще несколько вещей:

myModel.setCode("someCode"); 
doReturn("someCode").when(myModel.getCode()); 

Это не имеет смысла. Это не фальшивка, так что ... когда здесь нет смысла. И если бы это был макет, вызов сеттера был бы бесполезным.

assertEquals(classUnderTest.getDataByCode(eq("someCode")), myData); 

Также странно. Вы хотите вызвать getDataByCode, почему eq? Сделай это. Назови это. Написать:

assertEquals(classUnderTest.getDataByCode("someCode"), myData); 

Mockito-Matchers хороши, когда вы хотите проверить, что-то, но обычно не использовать их в качестве параметров для реальных вызовов методов.

verify(myService.getModelByCode(eq("someCode")), atLeastOnce()); 

Этот код действительно компилируется? Разве это не должно быть ...

verify(myService, atLeastOnce()).getModelByCode(eq("someCode")); 

Таким образом, было бы хорошая идея, чтобы фактически изолировать модульные тесты, насколько вы можете. Чем меньше внешних проблем вы приглашаете в свой тест, тем лучше может быть тест.

Метод, который я пытаюсь проверить, к сожалению, не имеет поля, он инициализирует это внутри метода, так что я не могу адресовать его.

Это просто звучит как запах кода, но без фактического кода, о котором идет речь, трудно сказать ...

+0

Спасибо. Да, фактический код не очень хорошо структурирован. Но вы обратились, что я имел в виду. Поскольку myModel не является макетом, нет смысла использовать doReturn. Но вызов метода setter не рекомендуется, так как мой Unit-Test затем зависит от него. Eq-part вы правы, я пытался упростить этот пример, поэтому я сделал небольшую ошибку. метод проверки в порядке, поскольку getModelByCode() возвращает модель, а не метод void. – user5417542

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