假设我有这样的课程:
public class StaticDude{
public static Object getGroove() {
// ... some complex logic which returns an object
};
}
如何使用 easy mock 模拟静态方法调用?StaticDude.getGroove()
.
我正在使用简单的模拟 3.0
假设我有这样的课程:
public class StaticDude{
public static Object getGroove() {
// ... some complex logic which returns an object
};
}
如何使用 easy mock 模拟静态方法调用?StaticDude.getGroove()
.
我正在使用简单的模拟 3.0
不确定如何使用纯 EasyMock,但考虑使用 EasyMock 的PowerMock扩展。
它有很多很酷的功能可以满足您的需求 - https://github.com/jayway/powermock/wiki/MockStatic
Easymock 是一个“用于接口(和通过类扩展的对象)”的测试框架,因此您可以在没有接口的情况下模拟一个类。考虑为您的静态类创建一个带有访问器的接口对象,然后改为模拟该访问器。
编辑:顺便说一句,我不建议做静态类。如果你在做 TDD,最好把所有东西都连接起来。
以防万一 PowerMock 因任何原因不可用:
您可以将静态调用移至方法,在测试类中的测试类的实例化中覆盖此方法,在测试类中创建本地接口并在覆盖的方法中使用其方法:
private interface IMocker
{
boolean doSomething();
}
IMocker imocker = EasyMock.createMock(IMocker.class);
...
@Override
void doSomething()
{
imocker.doSomething();
}
...
EasyMock.expect(imocker.doSomething()).andReturn(true);
一般来说,不使用某种访问器就不可能模拟静态方法,这似乎违背了使用静态方法的目的。这可能非常令人沮丧。
我知道有一个名为“TypeMock Isolator”的工具,它使用某种撒旦魔法来模拟静态方法,但该工具非常昂贵。
问题是,我不知道如何覆盖静态方法。您不能将其声明为虚拟的。您不能将其包含在界面中。
对不起,我是个消极的人。
添加一个示例,说明如何使用 EasyMock / PowerMock 沿注入类的常规模拟实现静态模拟,因为链接的示例仅显示静态模拟。
并用PowerMockRunner
服务@Mock
不连线对@TestSubject
服务进行测试。
假设我们有一个要测试的服务 ServiceOne :
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ServiceOne {
@Autowired
private ServiceTwo serviceTwo;
public String methodToTest() {
String returnServ2 = serviceTwo.methodToMock();
return ServiceUtils.addPlus(returnServ2);
}
}
它调用了我们要模拟的另一个服务 ServiceTwo :
import org.springframework.stereotype.Service;
@Service
public class ServiceTwo {
public String methodToMock() {
return "ServiceTwoReturn";
}
}
并调用最终类静态方法 ServiceUtils :
public final class ServiceUtils {
public static String addPlus(String pParam) {
return "+" + pParam;
}
}
调用时,ServiceOne.methodToTest()
我们得到"+ServiceTwoReturn"
作为回报。
使用 EasyMock 进行 Junit 测试,仅模拟注入的 ServiceTwo Spring 服务:
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static org.junit.Assert.assertEquals;
import org.easymock.EasyMockRunner;
import org.easymock.Mock;
import org.easymock.TestSubject;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(EasyMockRunner.class)
public class ExempleTest {
@TestSubject
private ServiceOne serviceToTest = new ServiceOne();
@Mock
private ServiceTwo serviceMocked;
@Test
public void testMethodToTest() {
String mockedReturn = "return2";
expect(serviceMocked.methodToMock()).andReturn(mockedReturn);
replay(serviceMocked);
String result = serviceToTest.methodToTest();
verify(serviceMocked);
assertEquals("+" + mockedReturn, result);
}
}
使用 EasyMock 和 PowerMock 进行 Junit 测试,模拟注入的 ServiceTwo Spring 服务以及最终类及其静态方法:
import static org.easymock.EasyMock.expect;
import static org.junit.Assert.assertEquals;
import static org.powermock.api.easymock.PowerMock.createMock;
import static org.powermock.api.easymock.PowerMock.mockStatic;
import static org.powermock.reflect.Whitebox.setInternalState;
import org.easymock.Mock;
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;
@RunWith(PowerMockRunner.class)
@PrepareForTest(ServiceUtils.class)
public class ExempleTest {
private ServiceOne serviceToTest;
private ServiceTwo serviceMocked;
@Before
public void setUp() {
serviceToTest = new ServiceOne();
serviceMocked = createMock(ServiceTwo.class);
// This will wire the serviced mocked into the service to test
setInternalState(serviceToTest, serviceMocked);
mockStatic(ServiceUtils.class);
}
@Test
public void testMethodToTest() {
String mockedReturn = "return2";
String mockedStaticReturn = "returnStatic";
expect(serviceMocked.methodToMock()).andReturn(mockedReturn);
expect(ServiceUtils.addPlus(mockedReturn)).andReturn(mockedStaticReturn);
PowerMock.replayAll();
String result = serviceToTest.methodToTest();
PowerMock.verifyAll();
assertEquals(mockedStaticReturn, result);
}
}