Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p><strong>For the mocks initialization</strong>, using the runner or the <code>MockitoAnnotations.initMocks</code> are strictly equivalent solutions. From the javadoc of the <a href="http://mockito.googlecode.com/svn/branches/1.6/javadoc/org/mockito/runners/MockitoJUnitRunner.html" rel="noreferrer">MockitoJUnitRunner</a> :</p> <p><em><code>JUnit 4.5 runner initializes mocks annotated with Mock, so that explicit usage of MockitoAnnotations.initMocks(Object) is not necessary. Mocks are initialized before each test method.</code></em></p> <hr> <p>The first solution (with the <code>MockitoAnnotations.initMocks</code>) could be used when you have already configured a specific runner (<code>SpringJUnit4ClassRunner</code> for example) on your test case.</p> <p>The second solution (with the <code>MockitoJUnitRunner</code>) is the more classic and my favorite. The code is simpler. Using a runner provides the great advantage of <strong><a href="http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html#validateMockitoUsage%28%29" rel="noreferrer">automatic validation of framework usage</a></strong> (described by <a href="https://stackoverflow.com/users/1081110/david-wallace">@David Wallace</a> in <a href="https://stackoverflow.com/questions/10806345/runwithmockitojunitrunner-class-vs-mockitoannotations-initmocksthis/10812752#10812752">this answer</a>).</p> <p>Both solutions allows to share the mocks (and spies) between the test methods. Coupled with the <a href="http://docs.mockito.googlecode.com/hg/latest/org/mockito/InjectMocks.html" rel="noreferrer"><code>@InjectMocks</code></a>, they allow to write unit tests very quickly. The boilerplate mocking code is reduced, the tests are easier to read. For example:</p> <pre><code>@RunWith(MockitoJUnitRunner.class) public class ArticleManagerTest { @Mock private ArticleCalculator calculator; @Mock(name = "database") private ArticleDatabase dbMock; @Spy private UserProvider userProvider = new ConsumerUserProvider(); @InjectMocks private ArticleManager manager; @Test public void shouldDoSomething() { manager.initiateArticle(); verify(database).addListener(any(ArticleListener.class)); } @Test public void shouldDoSomethingElse() { manager.finishArticle(); verify(database).removeListener(any(ArticleListener.class)); } } </code></pre> <p>Pros: The code is minimal </p> <p>Cons: Black magic. IMO it is mainly due to the @InjectMocks annotation. With this annotation <em>"you loose the pain of code"</em> (see the great comments of <a href="https://stackoverflow.com/users/48136/brice">@Brice</a>)</p> <hr> <p>The third solution is to create your mock on each test method. It allow as explained by <a href="https://stackoverflow.com/users/157672/mlk">@mlk</a> in its answer to have "<em>self contained test</em>".</p> <pre><code>public class ArticleManagerTest { @Test public void shouldDoSomething() { // given ArticleCalculator calculator = mock(ArticleCalculator.class); ArticleDatabase database = mock(ArticleDatabase.class); UserProvider userProvider = spy(new ConsumerUserProvider()); ArticleManager manager = new ArticleManager(calculator, userProvider, database); // when manager.initiateArticle(); // then verify(database).addListener(any(ArticleListener.class)); } @Test public void shouldDoSomethingElse() { // given ArticleCalculator calculator = mock(ArticleCalculator.class); ArticleDatabase database = mock(ArticleDatabase.class); UserProvider userProvider = spy(new ConsumerUserProvider()); ArticleManager manager = new ArticleManager(calculator, userProvider, database); // when manager.finishArticle(); // then verify(database).removeListener(any(ArticleListener.class)); } } </code></pre> <p>Pros: You clearly demonstrate how your api works (BDD...)</p> <p>Cons: there is more boilerplate code. (The mocks creation)</p> <hr> <p><strong>My</strong> recommandation is a compromise. Use the <code>@Mock</code> annotation with the <code>@RunWith(MockitoJUnitRunner.class)</code>, but do not use the <code>@InjectMocks</code> :</p> <pre><code>@RunWith(MockitoJUnitRunner.class) public class ArticleManagerTest { @Mock private ArticleCalculator calculator; @Mock private ArticleDatabase database; @Spy private UserProvider userProvider = new ConsumerUserProvider(); @Test public void shouldDoSomething() { // given ArticleManager manager = new ArticleManager(calculator, userProvider, database); // when manager.initiateArticle(); // then verify(database).addListener(any(ArticleListener.class)); } @Test public void shouldDoSomethingElse() { // given ArticleManager manager = new ArticleManager(calculator, userProvider, database); // when manager.finishArticle(); // then verify(database).removeListener(any(ArticleListener.class)); } } </code></pre> <p>Pros: You clearly demonstrate how your api works (How my <code>ArticleManager</code> is instantiated). No boilerplate code.</p> <p>Cons: The test is not self contained, less pain of code</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload