title: What are the key points to write good unit-tests with mocks
body: <p>I've been writting unit tests for an software for several weeks now, and I'm facing some doubts right now, concerning the design of my UT, their robustness and their maintainability.</p>
  
  <p>I'm writting my UT for a code in Java, with JUnit and EasyMock, because some of the objects called and used in the functions have a great level of complexity.</p>
  
  <p>Here's is my issues : </p>
  
  <ul>
  <li>I have the feeling that my test are just a copy of the functions I'm testing, mainly because I use mocks that need to be set up in adequacy with the algorithms</li>
  <li>My tests are quite repetitive, because when I began to work on the tests, I did not factorize the parts of the mocks setup I used in several tests, but also because I'm setting up different parameters and mocks for each test case of my UT (for example, i'm testing a function foo(A, B, C), and I found 5 test case that are interesting for this function, i'll have to setup 15 mocks)</li>
  </ul>
  
  <p>I'm aware that factorization and the re-use of mocks for every test case of a UT are a good solution to tackle this issues, and I've written some of them with these methodologies, but I've the feeling that it leads to a decrease in the robustness and the readability of the UT.</p>
  
  <p>Do you have any laws or tips you are trying to keep in mind while writing your UT that may be effective to tackle these issues .</p>
  
  <hr>
  
  <h2>Edit</h2>
  
  <p>For some clarification, here are some code examples :</p>
  
  <pre><code>public class functionsToTest{
  
     public static int getProperQuantity(Object A){
  
        int returnValue = 0;
  
        if(A != null &amp;&amp; A.getQuantity() != null &amp;&amp; A.getQuantity() &gt; 0){
            returnValue = A.getQuantity();
        }
  
        return returnValue;
  
     }
  
  }
  </code></pre>
  
  <p>Here is the class I want to test with UT. The object A is an complex object / object created with datas from a DB, so I have to mock it to write my UT.
  I have to way to write my UT tests :</p>
  
  <p><strong>1/ Create mocks and set them up for each test case</strong></p>
  
  <pre><code>public void myTest(){
     int expectedValue = 0;
     int output = 0;
  
     /** Setting up the mocks **/
     // Case 1 : A is null
  
     // Case 2 : A.getQuantity() is null
     Object A_case2 = createMock(A.class);
     EasyMock.expect(A_case2.getQuantity()).andReturn(null).anyTimes();
  
     // Case 3 : A.getQuantity() is negative
     Object A_case3 = createMock(A.class);
     EasyMock.expect(A_case3.getQuantity()).andReturn(-1).anyTimes();
  
     // Case 4 : nominal case
     Object A_case4 = createMock(A.class);
     EasyMock.expect(A_case4.getQuantity()).andReturn(5).anyTimes();
  
     // End Set Up
     EasyMock.replay(A_case2, A_case3, A_case4);
  
     /** Executing the tests **/
     // Case 1 : A is null
     expectedValue = 0;
     output = functionsToTest.getProperQuantity(null);
     assertEquals(expectedValue, output);
  
     // Case 2 : A.getQuantity() is null
     expectedValue = 0;
     output = functionsToTest.getProperQuantity(A_case2);
     assertEquals(expectedValue, output);
  
     // Case 3 : A.getQuantity() is negative
     expectedValue = 0;
     output = functionsToTest.getProperQuantity(A_case3);
     assertEquals(expectedValue, output);
  
     // Case 4 : nominal case
     expectedValue = 5;
     output = functionsToTest.getProperQuantity(A_case4);
     assertEquals(expectedValue, output);
  
  }
  </code></pre>
  
  <p>If find this solution quite robust and flexible, because if the function getProperQuantity changes in the future, it's quite simple to modify it. Plus, it's readable. The main drawback is the lenght (in my case, the set ups of the mocks are way longer, there are far more tests cases and the class I'm testing has 130 functions),the fact that it is redundant, and that it clearly follows the function I'm testing.</p>
  
  <p><strong>2/ Create a set of mocks for the whole unit test</strong></p>
  
  <pre><code>public void myTest(){
     int expectedValue = 0;
     int output = 0;
  
     /** Setting up the mocks **/
     Object A_default = createMock(A.class);
  
     // Case 1 : A is null
  
     // Case 2 : A.getQuantity() is null
     EasyMock.expect(A_default.getQuantity()).andReturn(null).times(1);
  
     // Case 3 : A.getQuantity() is negative
     EasyMock.expect(A_default.getQuantity()).andReturn(-1).times(2);
  
     // Case 4 : nominal case
     EasyMock.expect(A_default.getQuantity()).andReturn(5).times(3);
  
     // End Set Up
     EasyMock.replay(A_default);
  
     /** Executing the tests **/
     // Case 1 : A is null
     expectedValue = 0;
     output = functionsToTest.getProperQuantity(null);
     assertEquals(expectedValue, output);
  
     // Case 2 : A.getQuantity() is null
     expectedValue = 0;
     output = functionsToTest.getProperQuantity(A_default);
     assertEquals(expectedValue, output);
  
     // Case 3 : A.getQuantity() is negative
     expectedValue = 0;
     output = functionsToTest.getProperQuantity(A_default);
     assertEquals(expectedValue, output);
  
     // Case 4 : nominal case
     expectedValue = 5;
     output = functionsToTest.getProperQuantity(A_default);
     assertEquals(expectedValue, output);
  
  }
  </code></pre>
  
  <p>This solution is way shorter, easier, and quite readable too, but I've the feeling that there is a huge loss in robustness and flexibility : if the function I'm testing changes (even a little), the whole tests crashes and it needs to be totally redone. Plus, here again, it follows the code it should test.</p>