【问题标题】:Mock internal object method call using EasyMock使用 EasyMock 模拟内部对象方法调用
【发布时间】:2019-06-13 23:24:10
【问题描述】:
我有一堂课如下
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()});
然而,ClassB 对象在 classAMethod() 内部实例化。我如何模拟它并让它返回我想要的objectE?
基本上,我正在尝试测试 objectD.methodCall() 的不同场景,例如它返回异常和不同值集时的行为。
【问题讨论】:
标签:
java
unit-testing
junit
easymock
【解决方案1】:
正如 cmets 中提到的,您需要 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());
}
}