Note that there are some explanatory texts on larger screens.

plurals
  1. POWhat is the correct alternative to resetting a mock after setup in Mockito?
    primarykey
    data
    text
    <p>I'm new to unit testing and trying to learn the proper style. I like to setup the object that I am testing so that I can test it as if it were in use instead of only testing a newly constructed object. I can't test removing things from an object that is empty, as many objects are when constructed.</p> <p>Take the following for an example where ObservedList is being tested and ListListener is a necessary class that is being mocked.</p> <pre><code>public final class ObservedListTest { private ListListener&lt;Integer&gt; listener; private ObservedList&lt;Integer&gt; list; @BeforeMethod public void setup() { listener = mock(ListListener.class); list = new ObservedList&lt;Integer&gt;(listener); list.addAll(Arrays.asList(1,2,3)); reset(listener); } @Test public void addFirst() { list.add(0, -1); verify(listener).listEdited(list, 0, 1, Collections.&lt;Integer&gt;emptyList()); verifyNoMoreInteractions(listener); } @Test void addAtEnd() { list.add(9); verify(listener).listEdited(list, 3, 4, Collections.&lt;Integer&gt;emptyList()); verifyNoMoreInteractions(listener); } @Test void removeMiddle() { list.remove(Integer.valueOf(2)); verify(listener).listEdited(list, 1, 1, Collections.singletonList(2)); verifyNoMoreInteractions(listener); } } </code></pre> <p>As a novice this seems to work well to me, but I know that it's bad practice because it uses the <code>reset</code> method. I call <code>reset</code> because I don't want the actual tests to get confused due to interactions that happened in the setup.</p> <p>The javadoc for <code>reset</code> doesn't even get around to telling you what the method does because it is so busy telling you that you shouldn't use it. Ordinarily I'd simply take that advice and avoid <code>reset</code> by removing my <code>setup</code> method and adjusting my tests to look more like this:</p> <pre><code> @Test void removeMiddle() { listener = mock(ListListener.class); list = new ObservedList&lt;Integer&gt;(listener); list.addAll(Arrays.asList(1,2,3)); list.remove(Integer.valueOf(2)); InOrder inOrder = inOrder(listener); inOrder.verify(listener).listEdited(list, 0, 3, Collections.&lt;Integer&gt;emptyList()); inOrder.verify(listener).listEdited(list, 1, 1, Collections.singletonList(2)); verifyNoMoreInteractions(listener); } </code></pre> <p>This <em>also</em> seems to work well to me. The problem is that the documentation for the <code>reset</code> method says:</p> <blockquote> <p>Instead of reset() please consider writing simple, small and focused test methods over lengthy, over-specified tests.</p> </blockquote> <p>I respect that Mockito is designed to encourage good style in unit tests and I want to learn from it, but I'm having a hard time sorting out what message it is trying to send me. When I eliminate <code>reset</code> from my tests, my tests get <em>complex</em>, <em>longer</em> and <em>less focused</em>, so obviously I'm doing it wrong.</p> <p>What does doing it right look like?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

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