Expectation recorded on superclass method gets overwritten #209

Closed
Milbor opened this Issue Sep 17, 2015 · 2 comments

Projects

None yet

2 participants

@Milbor
Milbor commented Sep 17, 2015

Expectation recorded on superclass method on subclass object is overwritten if same expectation is recorded on different subclass object.

Best shown on following unit test (testng 6.9.6, jmockit 1.19) which I would expect to pass.
Is it bug? If not, could you elaborate on why it fails?

public class SpikeTest {
    public static class First extends Parent {
    }

    public static class Second extends Parent {
    }

    public static abstract class Parent {
        public String getValue() {
            return "parent";
        }
    }

    @Mocked
    private First first;
    @Mocked
    private Second second;

    @Test
    public void test() throws Exception {
        new Expectations() {{
            first.getValue();
            result = "first";

            second.getValue();
            result = "second"; //this recording overwrites previous recording on first object
        }};
        assertEquals(second.getValue(), "second");
        assertEquals(first.getValue(), "first"); //fails here, recorded "first" value is overwritten by "second"
    }
}
@rliesenfeld
Member

It's not a bug, even if in a case like this the mocking behavior is not what one would expect; well, unless you are familiar with the exact semantics of @Mocked.

Expectations recorded/verified on a @Mocked instance, by default, do not care about the actual instance used during replay (the one the code under test used); they will match regardless, considering only which method was called and any arguments and argument matchers.

If the instance on which the expectation was recorded needs to match the instances at replay time, then the test should use @Injectable rather than @Mocked. Alternatively, the test can use the "onInstance(mocked instance)" constraint to force instance matching.

@rliesenfeld rliesenfeld self-assigned this Sep 18, 2015
@rliesenfeld
Member

Perhaps @Mocked semantics can be improved here; I am thinking to add a check that the class of any mocked instance is the same as the @Mocked class, when comparing expectations and matching invocations to expectations.

@rliesenfeld rliesenfeld closed this Oct 4, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment