简体   繁体   中英

Using JMockit, how do I mock a static factory method to return a Fake?

Using the JMockit MockUp API, how do I mock a static factory method to return a Fake?

My question is similar to how do i mock the a static method that provides an instance of the class being mocked with JMockit? , with the added wrinkle that the factory method of my collaborator throws an exception in my test environment (and rightly so). Therefore, I need to mock the factory to stub out the problematic operations. The class with the factory method is abstract and has only a package-private constructor.

That is, given the following collaborator, how do I mock the collaboratorFactory() method such that it returns a fake Collaborator? (Collaborator is third party code over which I have no control.)

public abstract class Collaborator {
    public static Collaborator collaboratorFactory() {
        //... some operations that throw in test env ...
        return new CollaboratorImpl();
    }

    Collaborator() { }

    public int methodToMock() {
        return 5;
    }
}

My class under test does:

public class ClassUnderTest {
    public int getValue() {
        return Collaborator.collaboratorFactory().methodToMock();
    }
}

I want to test "ClassUnderTest" with a fake Collaborator that, say, returns some known value from "methodToMock()" I've defined my test class as such:

public class TestClassUnderTest {

    static class MockCollaborator extends MockUp<Collaborator> {
        @Mock public int methodToMock() {
            return 124;
        }
    }

    @Test
    public void test1() throws Exception {
        new MockCollaborator();
        ClassUnderTest t1 = new ClassUnderTest();
        assertEquals(124, t1.getValue());
    }

}

This test fails when Collaborator.collaboratorFactory() throws an exception in my test environment. What I really want to do is stub out collaboratoryFactory() such that it just returns the fake Collaborator. Something like the following, perhaps:

    static class MockCollaborator extends MockUp<Collaborator> {
        @Mock public Collaborator collaboratorFactory() {
            // ... I don't know what to return here ...
        }
    }

In the body of the collaboratorFactory() mock method (above), I've tried returning this.getMockInstance(), but it returns null as the actual method to be mocked is static.

FWIW, I have been able to use the Expectations API to test what I need to test, but I feel like this should be possible using the MockUp API as well.

Any help or suggestions are appreciated.

Because the Collaborator is abstract, I had to do this with two MockUps, one for the Collaborator, and one for the CollaboratorImpl. The factory method in the abstract class returns an instance of the fake implementation class via getMockedInstance():

static class MockCollaboratorImpl extends MockUp<CollaboratorImpl> {
    @Mock public void $init() {};
    @Mock public void $clinit() {};
    @Mock public int methodToMock() {
        return 124;
    }
}

static class MockCollaborator extends MockUp<Collaborator> {
    @Mock public Collaborator collaboratorFactory() {
        return new MockCollaboratorImpl().getMockInstance();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM