15

This follows on from this question: where I am asked to start a new question.

The problem is that I just don't know enough about JUnit Rule, or what's going on here with Runners and the like, to crack the problem in the way alluded to by Jeff Bowman.

Community
  • 1
  • 1
mike rodent
  • 14,126
  • 11
  • 103
  • 157
  • Did you go through the tutorial? http://www.vogella.com/tutorials/JUnit/article.html it also has a section for parameterized tests – Timothy Truckle Nov 24 '16 at 19:37
  • @TimothyTruckle the point of my question is that I want to use Mockito, which uses its own RunWith annotation if you want (in particular) to inject mocks. This is the problem. I have reason to believe Jeff Bowman can answer the question. But he wanted me to start a new question... – mike rodent Nov 24 '16 at 19:40
  • @mikerodent The tutorial will answer all your questions about mockito. The question is: do you want to learn something or do you want a solution to copy? – Timothy Truckle Nov 24 '16 at 19:46
  • @TimothyTruckle well I visited that page you suggested and searched Mockito... there is one link to an "intro to Mockito". But I couldn't find anywhere which suggests how to do parameterised testing. Actually a solution to copy is, in my experience, an excellent way to start learning sthg. So if you have an example to show me, I'd be very grateful if you could answer the question. – mike rodent Nov 24 '16 at 19:49
  • You're becoming quite annoying now. You cannot combine two `RunWith` annotations. Therefore it is not possible to combine `RunWith(MockitoJUnitRunner.class)` with `RunWith(Parameterized.class)`. You need to think about this rather than assuming people are younger or more stupid than yourself. – mike rodent Nov 24 '16 at 20:10

1 Answers1

31

In your later comments, I figured out the gap: You need to use Mockito as a Rule and Parameterized as a Runner, not the other way around.

The reason is that the Runner is responsible for reporting the number of tests, and Parameterized manipulates the number of tests based on the number of test methods and the number of parameterized inputs, so it's really important for Parameterized to be a part of the Runner process. By contrast, the use of a Mockito runner or rule is simply to encapsulate the @Before and @After methods that initialize Mockito annotations and validate Mockito usage, which can be done very easily as a @Rule that works adjacent to other @Rule instances--to the point that the MockitoJUnitRunner is very nearly deprecated.

To crib directly from the JUnit4 Parameterized Test doc page and MockitoRule doc page:

@RunWith(Parameterized.class)
public class YourComponentTest {

    @Rule public MockitoRule rule = MockitoJUnit.rule();
    @Mock YourDep mockYourDep;

    @Parameters
    public static Collection<Object[]> data() {
        return Arrays.asList(new Object[][] {     
                 { 0, 0 }, { 1, 1 }, { 2, 1 }, { 3, 2 }, { 4, 3 }, { 5, 5 }, { 6, 8 }  
           });
    }

    private int fInput;

    private int fExpected;

    public YourComponentTest(int input, int expected) {
        fInput = input;
        fExpected = expected;
    }

    @Test
    public void test() {
        // As you may surmise, this is not a very realistic example of Mockito's use.
        when(mockYourDep.calculate(fInput)).thenReturn(fExpected);
        YourComponent yourComponent = new YourComponent(mockYourDep);
        assertEquals(fExpected, yourComponent.compute(fInput));
    }
}
mike rodent
  • 14,126
  • 11
  • 103
  • 157
Jeff Bowman
  • 90,959
  • 16
  • 217
  • 251
  • Is it possible to mock the data too? i.e `@Mock private int fInput` ? – Atieh Jan 08 '18 at 19:21
  • 1
    @Atieh Of course; I've done so above. The parameterization governs how many times the test is run and how the test class is instantiated, and then MockitoRule governs how `@Mock` parameters are populated within each test case (i.e. within each test class instance). As long as the Parameterized runner is in the `@RunWith` annotation and Mockito initialization happens some way or another, the two work fine together. – Jeff Bowman Jan 08 '18 at 22:32