Search code examples
javajunitjmockit

How to update code from Jmockit 1.1 to 1.9 to Access Real Instance?


I am trying to update code from Jmockit 1.1 to 1.9 to Access Real Instance, But it seems to be unsuccessful as below:

    java.lang.IllegalArgumentException: Matching real methods not found for the following mocks:
CopyOfAccessRealInstanceTest$1#getRealInstanceName(String m, mockit.Invocation inv)
    at CopyOfAccessRealInstanceTest$1.<init>(CopyOfAccessRealInstanceTest.java:28)
    at CopyOfAccessRealInstanceTest.mockConstructor(CopyOfAccessRealInstanceTest.java:28)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

I think it is due to mock method:

        @Mock(invocations = 1)
        public String getRealInstanceName(String m,Invocation inv)

-------------------------Codes 1.9---------------------------------

public class CopyOfAccessRealInstanceTest {  
    private Constructor constructor = new Constructor("");  

    @Test
    public void mockConstructor() {
        // Mockit.setUpMock(Constructor.class, new MockedConstructor());
        MockUp<Constructor> mockup = new MockUp<Constructor>() {
            //public Constructor it;

            @Mock(invocations = 1)
            public String getRealInstanceName(String m,Invocation inv)
            {           
                if ("real".equals(m)) {
                    return inv.proceed(inv.getInvokedArguments());
                    // return it.getRealInstanceName(m);
                } else {
                    return "mock";
                }
            }
        };

        Assert.assertEquals("mock",
                                constructor.getRealInstanceName(""));
        Assert.assertEquals("real_m_real",
            constructor.getRealInstanceName("real"));
    }
}

-----------------------Code of Jmock 1.1--------------------------------

public class AccessRealInstanceTest {
    private Constructor constructor = new Constructor("");

    @Test
    public void mockConstructor() {
        Mockit.setUpMock(Constructor.class, new MockedConstructor());
        Assert.assertEquals("real_m_real",
                   constructor.getRealInstanceName("real"));
    }

    public static class MockedConstructor {
        public Constructor it;
        @Mock(reentrant = true)//reentrant allow to access real instance
        public String getRealInstanceName(String m) {
            if ("real".equals(m)) {
                return it.getRealInstanceName(m);
            } else {
                return "mock";
            }
        }
    }
}

Class to be Mocked:

public class Constructor {
    private String memberId;  

    public Constructor(String memberId) {  
        this.memberId = memberId;  
    }  

    public String getRealName() {  
        return "real_" + this.memberId;  
    }  

    public String getRealInstanceName(String m) {
        return "real_m_" + m;
    }
}

Solution

  • It is resolved. Thank you for Rogério and Sean!

    Note the API documentation says that an Invocation parameter must be the first parameter in the mock method. – Rogério