Ar3*_*r3s 5 java unit-testing easymock powermock
我有一个简单的案例来说明一个更复杂的案例(哦,Legacy Code,我爱你吗,吟游诗人应该以你的名义唱出美妙的歌曲)。
一组类的图片如下:
package org.osef.test;
public final class A {
private static A instance;
public static String status;
private A() {
initPaths();
}
public static A getInstance(){
if(instance==null){
instance = new A();
}
return instance;
}
private void initPaths() {
A.status = "I have been in the method !";
}
public String doStuff() {
return "stuff done ...";
}
}
Run Code Online (Sandbox Code Playgroud)
package org.osef.test;
public class B {
public String doBdo() {
A instance = A.getInstance();
return instance.doStuff();
}
}
Run Code Online (Sandbox Code Playgroud)
包 org.osef.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import org.easymock.EasyMock;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.reflect.Whitebox;
@RunWith(PowerMockRunner.class)
@PrepareForTest({ A.class })
public class BTest {
@Before
public void setUp() {
PowerMock.replace(PowerMock.method(A.class, "getInstance")).with(PowerMock.method(BTest.class, "giveOutInstance"));
A a = A.getInstance();
EasyMock.expect(a.doStuff()).andReturn("lol");
EasyMock.replay(a);
}
@Test
public void testDoBdo() {
B b = new B();
assertEquals("lol", b.doBdo());
assertNull(A.status);
}
public static A giveOutInstance(){
return Whitebox.newInstance(A.class);
}
}
Run Code Online (Sandbox Code Playgroud)
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import org.easymock.EasyMock;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.reflect.Whitebox;
@RunWith(PowerMockRunner.class)
@PrepareForTest({ A.class })
public class BTest {
@Before
public void setUp() {
PowerMock.replace(PowerMock.method(A.class, "getInstance")).with(PowerMock.method(BTest.class, "giveOutInstance"));
A a = A.getInstance();
EasyMock.expect(a.doStuff()).andReturn("lol");
EasyMock.replay(a);
}
@Test
public void testDoBdo() {
B b = new B();
assertEquals("lol", b.doBdo());
assertNull(A.status);
}
public static A giveOutInstance(){
return Whitebox.newInstance(A.class);
}
}
Run Code Online (Sandbox Code Playgroud)
但在所有情况下,我都得到:
java.lang.IllegalStateException: 在 org.easymock.EasyMock.getControlForLastCall(EasyMock.java:560) at org.easymock.EasyMock.expect(EasyMock.java:538) at org.osef.test 上没有对模拟可用的最后一次调用。 BTest.setUp(BTest.java:25) ...
知道如何有效地做我想做的事吗?
我认为你的问题是你没有重播这些类,你只是在每个测试中重播 A 的模拟实例。
PowerMock.replayAll()是你的朋友吗?它将强制您期望的类处于重播模式,然后可以通过调用静态方法返回您的模拟实例。
这是我为您的示例制作的示例测试:
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import org.easymock.EasyMock;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest(A.class)
public class BTest{
@Test
public void thatCallingClassMakesExpectedCalls() {
final A mockA = PowerMock.createMock(A.class);
EasyMock.expect(mockA.doStuff()).andReturn("lol").anyTimes();
PowerMock.mockStatic(A.class);
EasyMock.expect(A.getInstance()).andReturn(mockA).anyTimes();
PowerMock.replayAll(mockA);
final B callingClass = new B();
final String doBdo = callingClass.doBdo();
assertThat(doBdo, is("lol"));
EasyMock.verify(mockA);
PowerMock.verifyAll();
}
}
Run Code Online (Sandbox Code Playgroud)