Question

If writing a Java unit test with mocking using JMock, should we use

Mockery context = new Mockery()

or

Mockery context = new JUnit4Mockery()

What is the difference between the two, and when should we use which?

Was it helpful?

Solution

@Rhys It's not the JUnit4Mockery that replaces the need to call assertIsSatisfied, its the JMock.class (combined with the @RunWith). You wont need to call assertIsSatisfied when you create a regular Mockery.

The JUnit4Mockery translates errors.

By default, expectation exceptions are reported in Junit as ExpectationError, so for example, using

Mockery context = new Mockery();

you'll get

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?

and using,

Mockery context = new JUnit4Mockery();

you'll get

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!

The JUnit4Mockery converted the ExpectationError to an java.lang.AssertionError which JUnit deals with. Net result is that it'll show up in your JUnit report as an failure (using JUnit4Mockery) rather than an error.

OTHER TIPS

When using JMock with JUnit 4, you can avoid some boilerplate code by taking advantage of the JMock test runner. When you do this, you must use the JUnit4Mockery instead of the regular Mockery.

Here is how you'd structure a JUnit 4 test:

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

}

The main advantage is there is no need to call assertIsSatisfied in each test, it is called automatically after each test.

Better yet, per http://incubator.apache.org/isis/core/testsupport/apidocs/org/jmock/integration/junit4/JUnitRuleMockery.html use @Rule and avoid @RunWith which you might need for some other system:

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();
     }
 }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top