Условная проверка Mockito с фабриками

Возможно ли в mockito проверить, был ли вызван метод для макета, основываясь на том, действительно ли макет использовался в тестируемом модуле?

В качестве простого примера я предоставляю макет фабрики (FooFactory) моему тестируемому модулю, и когда вызывается Foo.create(), он возвращает макет (Foo), который будет использоваться определенными методами в тестируемом модуле. тест. Как я могу убедиться, что Foo.method() вызывается только в том случае, если Foo.create() вызывается тестируемым модулем?

Я предполагаю, что код будет выглядеть примерно так:

@Before
public void init() {
  Foo mockFoo = mock(Foo.class);
  when(fooFactory.create()).thenReturn(mockFoo);
  test = new UnitUnderTest(fooFactory);
}

@Test
... may or may not create a foo ...

@After
public void cleanup() {
  if (verify(fooFactory).create()) {  // Here's the 'conditional verification'
    Foo mockFoo = fooFactory.create();
    verify(mockFoo).close();
  }
}

В качестве более конкретного примера моя фабрика возвращает объект Reader, который я хочу гарантировать, что он закрыт, но не каждый метод в классе фактически создает Reader. Очевидно, я мог бы добавить проверку к каждому тесту, где я знаю, что Reader необходим, но это похоже на дублирование усилий.


person thebamaman    schedule 09.12.2010    source источник


Ответы (2)


Вы уверены, что хотите написать этот тест?

Я вижу два решения:

1) Вы действительно хотите убедиться, что ресурс создан и закрыт, поэтому попробуйте написать тест, в котором вы можете проверить вызовы обоих методов.

2) Вы хотите убедиться, что всякий раз, когда ресурс открывается, он также закрывается. Это может быть реализовано как утверждение в производственном коде...

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

Также вы должны делать проверку не в очистке, а в самом методе тестирования.

person Felix Leipold    schedule 09.12.2010
comment
+1. Вы можете создать отдельный модульный тест для обоих случаев (например, testWasInteraction, testNoInteraction) и не иметь никакой другой проверки в методах очистки. Итог - если вы хотите эту проверку, напишите конкретный модульный тест. В конце концов, если будет ошибка, вы захотите увидеть один сбой теста, а не несколько сбоев в каждом тестовом примере, использующем этот метод. - person Petro Semeniuk; 10.12.2010

Честно говоря, кажется, что ваш тест слишком сложен. Мой опыт работы со многими проектами и большим количеством модульных тестов показал, что лучший способ справиться с вещами — убедиться, что каждый тест проверяет только одну вещь. У вас может быть сколько угодно утверждений, но должен вызываться один метод и тестироваться один сценарий. Что-нибудь мо и тест становится слишком сложным. Кроме того, другим разработчикам очень сложно пройти тест на более позднем этапе при дальнейшей разработке приложения.

Поэтому я бы предложил разбить ваш тест на несколько тестов, по одному на каждый сценарий, а затем посмотреть, нужен ли он вам.

person drekka    schedule 10.12.2010