Search code examples
javaunit-testingjunitjmockitexpectations

Stopping mocking in Jmockit


I am using JMockit. I am mocking a method. I want that mocked method should be called once after that actual method should be called. I am providing the code I am using.

package StopMocking;
public class ClassToMock 
{
    public int methodToMock()
    {
        return 2;
    }
}

This is the class I am testing

package StopMocking;
public class ClassToTest 
{
    public void methodToTest()
    {
        ClassToMock classToMockInstance = new ClassToMock();
        System.out.println(""+classToMockInstance.methodToMock());
    }
}

This is the test class.

package StopMocking;
import org.junit.Test;
import mockit.Mocked;
import mockit.NonStrictExpectations;
public class TestAClass 
{
    @Mocked("methodToMock") ClassToMock classToMockMockedInstance;
    @Test
    public void test1()
    {

        new Expectations(classToMockMockedInstance)
        {
            {
            classToMockMockedInstance.methodToMock();returns(1);
            }
        };

        (new ClassToTest()).methodToTest();
        //Some code for stoping mocking
        (new ClassToTest()).methodToTest();//It should display 2

    }
}

When I am using new Expectations(classToMockMockedInstance) it is throwing this exception

mockit.internal.MissingInvocation: Missing invocation of:
StopMocking.ClassToMock#methodToMock()
   on mock instance: StopMocking.ClassToMock@15093f1
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: Missing invocation
    at StopMocking.ClassToMock.methodToMock(ClassToMock.java)
    at StopMocking.TestAClass$1.<init>(TestAClass.java:21)
    at StopMocking.TestAClass.test1(TestAClass.java:18)
    ... 6 more

Solution

  • One way to write the test is to as follows, using partial mocking and strict expectations:

    public class TestAClass 
    {
        @Test
        public void test1()
        {
            final ClassToMock classToMockInstance = new ClassToMock();
    
            new Expectations(ClassToMock.class) {{
                classToMockInstance.methodToMock(); result = 1;
            }};
    
            new ClassToTest().methodToTest(); // prints "1"
    
            // This time the real method implementation will be executed:
            new ClassToTest().methodToTest(); // prints "2"
        }
    }