Question

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?

Update (with the solution)

As @Rogério mentioned, this behavior is not acceptable.
Then how can the mock be overridden? like this:

private MockUp<Dummy> mock;

@Test
public void test3() {

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


private void mockCorrectly(final String s) {

    if (mock != null) {
        mock.tearDown();
    }

    mock = new MockUp<Dummy> {

        @Mock
        public void foo(Invocation inv) {

            System.out.println(s);
            inv.proceed();
        }
    }
}

And for the output:

B
O

Great :)

Was it helpful?

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top