简体   繁体   中英

Mock internal object method call using EasyMock

I have a class as follows

class ClassA {
    public FinalObject classAMethod() {
        ClassB objectB = new ClassB();
        FinalObject objectE = objectB.methodCall();
        return objectE;
    }
}

Now using EasyMock i can do

ClassB objectB = EasyMock.createMock(ClassB.class);

EasyMock.expect(objectB.methodCall())).andReturn(new FinalObject()});

However for ClassB object is instantiated inside classAMethod() . How do I mock it and make it return the objectE I want?

Basically, I am trying to test out different scenarios for objectD.methodCall() such as the behavior when it returns exceptions and different set of values.

As mentioned in the comments, you need PowerMock to do such a thing. Here is an example.

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.mock;
import static org.junit.Assert.assertSame;
import static org.powermock.api.easymock.PowerMock.expectNew;
import static org.powermock.api.easymock.PowerMock.replay;

class ClassA {
    public FinalObject classAMethod() {
        ClassB objectB = new ClassB();
        FinalObject objectE = objectB.methodCall();
        return objectE;
    }
}

class ClassB {

    public FinalObject methodCall() {
        return null;
    }
}

class FinalObject {}

@RunWith(PowerMockRunner.class)
@PrepareForTest(ClassA.class)
public class MyTest {

    @Test
    public void test() throws Exception {
        ClassB mock = mock(ClassB.class);

        expectNew(ClassB.class).andReturn(mock);

        FinalObject value = new FinalObject();
        expect(mock.methodCall()).andReturn(value);

        replay(mock, ClassB.class);

        ClassA a = new ClassA();
        assertSame(value, a.classAMethod());
    }
}

However, I do try to use PowerMock as less as possible. Instantiating a class and then call it is frequently a code smell. Then, if I really need to do that for some reason, I would generally isolate the class instantiation to another method. It gives me the same result without PowerMock dark magic.

import org.junit.Test;

import static org.easymock.EasyMock.*;
import static org.junit.Assert.assertSame;

class ClassA {
    public FinalObject classAMethod() {
        ClassB objectB = newB();
        return objectB.methodCall();
    }

    ClassB newB() {
        return new ClassB();
    }
}

class ClassB {

    public FinalObject methodCall() {
        return null;
    }
}

class FinalObject {}

public class MyTest {

    @Test
    public void test() {
        ClassB b = mock(ClassB.class);
        ClassA a = partialMockBuilder(ClassA.class)
                .addMockedMethod("newB")
                .mock();

        FinalObject value = new FinalObject();
        expect(b.methodCall()).andReturn(value);

        expect(a.newB()).andReturn(b);

        replay(a, b);

        assertSame(value, a.classAMethod());
    }
}

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