Search code examples
junitconstructortestcasejmockit

jmockit mocked constructor not returning expected value


I am trying to unit test a class where one of its methods returns an instance of a collaborator class: depending on the values of its arguments it either returns a newly created instance, or a saved, previously created instance.

I mock the constructor call in an Expectations and set the result to a value that is a mocked instance of the collaborator. But when I test the method with parameter values that cause it to create a new instance, the mocked constructor, and therefore the method, does not return the expected value.

I have simplified this down to the following:

package com.mfluent;
import junit.framework.TestCase;
import mockit.Expectations;
import mockit.Mocked;
import mockit.Tested;
import org.junit.Assert;
import org.junit.Test;

public class ConstructorTest extends TestCase {

    static class Collaborator {
    }

    static class ClassUnderTest {
        Collaborator getCollaborator() {
            return new Collaborator();
        }
    }

    @Tested
    ClassUnderTest classUnderTest;

    @Mocked
    Collaborator collaborator;

    @Test
    public void test() {
        new Expectations() {
            {
                new Collaborator();
                result = ConstructorTest.this.collaborator;
            }
        };

        Collaborator collaborator = this.classUnderTest.getCollaborator();
        Assert.assertTrue("incorrect collaborator returned", collaborator == this.collaborator);
    }
}

Any ideas on why this test fails and how to make it work would br greatly appreciated.

Thanks in advance,

Jim Renkel Senior Technical Staff mFluent, Inc. LLC


Solution

  • Change the @Mocked annotation to @Capturing, like this:

    @Capturing
    Collaborator collaborator;
    

    This allows the test to pass for me.

    This is a little bit of voodoo magic, in my opinion, but if you'd like to read more, take a look at Capturing internal instances of mocked types in the JMockit tutorial.

    Also see Using JMockit to return actual instance from mocked constructor