如何模拟实现类?

use*_*407 5 java junit unit-testing mockito powermockito

我有这样的事情:

public interface SomeInterface {
    public String someMethod(String someArg1, String someArg2);
}

public class SomeInterfaceImpl {

    @Override
    public String someMethod(String someArg1, String someArg2) {
        String response;

        // a REST API call which fetches response (need to mock this)

        return response;
    }
}

public class SomeClass {

    public int execute() {

        int returnValue;

        // some code

        SomeInterface someInterface = new SomeInterfaceImpl();
        String response = someInterface.someMethod("some1", "some2");

        // some code

        return returnValue;
    }
}
Run Code Online (Sandbox Code Playgroud)

我想execute()SomeClass使用 JUnit 时测试该方法。由于someMethod(String someArg1, String someArg2)调用了 REST API,我想模拟someMethod返回一些预定义的响应。但不知何故, realsomeMethod被调用而不是返回预定义的响应。我如何使它工作?

这是我使用 Mockito 和 PowerMockito 尝试过的:

@RunWith(PowerMockRunner.class)
@PrepareForTest({ SomeInterface.class, SomeInterfaceImpl.class, SomeClass.class })
public class SomeClassTest {

    @Test
    public void testExecute() {
        String predefinedResponse = "Some predefined response";
        int expectedReturnValue = 10;

        SomeInterfaceImpl impl = PowerMockito.mock(SomeInterfaceImpl.class);
        PowerMockito.whenNew(SomeInterfaceImpl.class).withAnyArguments().thenReturn(impl);
        PowerMockito.when(impl.someMethod(Mockito.any(), Mockito.any())).thenReturn(predefinedResponse);

        SomeClass someClass = new SomeClass();
        int actualReturnValue = someClass.execute();
        assertEquals(expectedReturnValue, actualReturnValue);
      }
}
Run Code Online (Sandbox Code Playgroud)

Gho*_*ica 1

你不必这样做。

您将被测试的方法更改为不直接调用 new。

例如,您可以使用依赖注入。

是的,这可以用 Powermock 来完成,但请相信我:这样做是错误的方法!

  • 依赖注入并不意味着使用 DI 框架:它只是意味着您以某种方式将依赖项传递到实例中 - 构造函数参数、setter、DI 框架... (2认同)