Когда мы должны использовать Mockery vs JUnit4Mockery?

Если вы пишете Java unit test с насмешкой с помощью JMock, мы должны использовать

Mockery context = new Mockery()

или

Mockery context = new JUnit4Mockery()

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

Ответ 1

@Rhys Это не JUnit4Mockery, который заменяет необходимость вызова assertIsSatisfied, его JMock.class (в сочетании с @RunWith). Вам не нужно вызывать assertIsSatisfied при создании регулярного Mockery.

JUnit4Mockery преобразует ошибки.

По умолчанию исключения ожидания отображаются в Junit как ExpectationError, поэтому, например, используя

Mockery context = new Mockery();

вы получите

unexpected invocation: bar.bar()
no expectations specified: did you...
 - forget to start an expectation with a cardinality clause?
 - call a mocked method to specify the parameter of an expectation?

и используя

Mockery context = new JUnit4Mockery();

вы получите

java.lang.AssertionError: unexpected invocation: bar.bar()
no expectations specified: did you...
 - forget to start an expectation with a cardinality clause?
 - call a mocked method to specify the parameter of an expectation?
what happened before this: nothing!

JUnit4Mockery преобразовал ExpectationError в java.lang.AssertionError, с которым работает JUnit. Результатом Net является то, что он будет отображаться в отчете JUnit как сбой (с использованием JUnit4Mockery), а не с ошибкой.

Ответ 2

При использовании JMock с JUnit 4 вы можете избежать некоторого кода шаблона, воспользовавшись тестовым бегуном JMock. Когда вы это сделаете, вы должны использовать JUnit4Mockery вместо обычной Mockery.

Вот как вы бы структурировали тест JUnit 4:

@RunWith(JMock.class)
public void SomeTest() {
  Mockery context = new JUnit4Mockery();

}

Главное преимущество - не нужно вызывать assertIsSatisfied в каждом тесте, он вызывается автоматически после каждого теста.

Ответ 3

Еще лучше, за http://incubator.apache.org/isis/core/testsupport/apidocs/org/jmock/integration/junit4/JUnitRuleMockery.html использовать @Rule и избегать @RunWith, который может понадобиться для какой-либо другой системы:

public class ATestWithSatisfiedExpectations {
     @Rule
     public final JUnitRuleMockery context = new JUnitRuleMockery();
     private final Runnable runnable = context.mock(Runnable.class);

     @Test
     public void doesSatisfyExpectations() {
         context.checking(new Expectations() {
             {
                 oneOf(runnable).run();
             }
         });

         runnable.run();
     }
 }