javamockingjmockit

JMockit: How to override already mocked method with a new mock?


I think I might have found a bug in JMockit, but I would like some to confirm whether it's a bug or there's something I'm missing.

I have the following (very simple) class:

public class Dummy {
    public void foo() {System.out.println("O");}
}

Now I have the following tests, where in each of them I try to mock the method 'foo' more than once (each test does it a little differently):

Test #1

@Test
public void test1() {

    new MockUp<Dummy>() {
        
        @Mock
        public void foo(Invocation inv) {
            
            System.out.println("A");
            inv.proceed();
        }
    }

    new MockUp<Dummy>() {
        
        @Mock
        public void foo(Invocation inv) {
            
            System.out.println("B");
            inv.proceed();
        }
    }

    new Dummy().foo();
}

Test #2

@Test
public void test2() {

    mock("A");
    mock("B");
    new Dummy().foo();
}

private void mock(final String s) {

    new MockUp<Dummy>() {
        
        @Mock
        public void foo(Invocation inv) {
            
            System.out.println(s);
            inv.proceed();
        }
    }
}

The only difference between the tests is the extraction of the mock code to a different method. But the results are not the same...

Test #1 output:

B
A
B
O

This is odd, because I wouldn't expect A to appear at all. But anyway, here's test #2 output:

B
A
A
A
...ad infinitum

Test #2 will fail with a StackOverflowError.

Is this a bug or am I missing something?


Solution

  • It's not clear what exactly happens here; apparently, at runtime some "chained mocking" is occurring.

    The real problem is that both tests are doing something invalid with the MockUp API: they are mocking the same method in the same class twice in the same test. It is ok to have two different mock-ups for the same class in the same test, as long as they mock different methods/constructors.

    The resulting behavior is undefined, as JMockit does not support multiple simultaneous mockings of the same method.