使用EasyMock模拟内部对象方法调用

时间:2019-06-13 23:24:10

标签: java unit-testing junit easymock

我有一个如下的课程

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

现在我可以使用EasyMock了

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

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

但是,在classAMethod()内部实例化了ClassB对象。如何模拟它并使其返回我想要的objectE

基本上,我正在尝试测试objectD.methodCall()的不同方案,例如它返回异常和不同值集时的行为。

1 个答案:

答案 0 :(得分:0)

如评论中所述,您需要PowerMock来执行此操作。这是一个例子。

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());
    }
}

但是,我确实尝试尽可能少地使用PowerMock。实例化一个类然后调用它通常是一种代码味道。然后,如果由于某种原因确实需要这样做,则通常将类实例化隔离到另一个方法。没有PowerMock黑暗魔法,我得到的结果也一样。

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());
    }
}