34

假设我有这样的课程:

public class StaticDude{
    public static Object getGroove() {
        // ... some complex logic which returns an object
    };
}

如何使用 easy mock 模拟静态方法调用?StaticDude.getGroove().

我正在使用简单的模拟 3.0

4

5 回答 5

26

不确定如何使用纯 EasyMock,但考虑使用 EasyMock 的PowerMock扩展。

它有很多很酷的功能可以满足您的需求 - https://github.com/jayway/powermock/wiki/MockStatic

于 2010-07-02T00:44:20.633 回答
11

Easymock 是一个“用于接口(和通过类扩展的对象)”的测试框架,因此您可以在没有接口的情况下模拟一个类。考虑为您的静态类创建一个带有访问器的接口对象,然后改为模拟该访问器。

编辑:顺便说一句,我不建议做静态类。如果你在做 TDD,最好把所有东西都连接起来。

于 2010-07-02T00:51:11.117 回答
10

以防万一 PowerMock 因任何原因不可用:

您可以将静态调用移至方法,在测试类中的测试类的实例化中覆盖此方法,在测试类中创建本地接口并在覆盖的方法中使用其方法:

private interface IMocker 
{
    boolean doSomething();
}

IMocker imocker = EasyMock.createMock(IMocker.class);

...

@Override
void doSomething()
{
     imocker.doSomething();
}

...

EasyMock.expect(imocker.doSomething()).andReturn(true);
于 2012-08-30T08:41:00.167 回答
4

一般来说,不使用某种访问器就不可能模拟静态方法,这似乎违背了使用静态方法的目的。这可能非常令人沮丧。

我知道有一个名为“TypeMock Isolator”的工具,它使用某种撒旦魔法来模拟静态方法,但该工具非常昂贵。

问题是,我不知道如何覆盖静态方法。您不能将其声明为虚拟的。您不能将其包含在界面中。

对不起,我是个消极的人。

于 2010-07-07T16:40:02.373 回答
1

添加一个示例,说明如何使用 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);
    }
}
于 2017-02-16T13:41:37.103 回答