Java 单元测试失败,因为服务处于脱机状态

Java 单元测试失败,因为服务处于脱机状态,java,unit-testing,mockito,powermock,Java,Unit Testing,Mockito,Powermock,我有一个单元测试失败,因为它间接调用了依赖于服务的方法。但是当单元测试运行时,服务是离线的。我尝试使用Mockito来模拟这个依赖于服务的方法的行为,但问题是这个方法是最后一个类中的静态方法,所以Mockito在这种情况下不起作用 我还尝试将PowerMock与Mockito结合使用,但由于该方法不是直接从单元测试调用的,因此它不起作用。这是我的单元测试的框架: @RunWith(PowerMockRunner.class) @PrepareForTest(FinalClassWithStati

我有一个单元测试失败,因为它间接调用了依赖于服务的方法。但是当单元测试运行时,服务是离线的。我尝试使用Mockito来模拟这个依赖于服务的方法的行为,但问题是这个方法是最后一个类中的静态方法,所以Mockito在这种情况下不起作用

我还尝试将PowerMock与Mockito结合使用,但由于该方法不是直接从单元测试调用的,因此它不起作用。这是我的单元测试的框架:

@RunWith(PowerMockRunner.class)
@PrepareForTest(FinalClassWithStaticMethod.class)
public class MyObjTestCase {
    @Test public void myRandomTest() throws Exception {
        PowerMockito.mockStatic(FinalClassWithStaticMethod.class);
        MyObj returnObj = new MyObj();
        // setup fields for returnObj
        ...
        ...
        PowerMockito.when(FinalClassWithStaticMethod.staticMethod((AnotherObj)anyObject())).thenReturn(returnObj);
        AnotherObj obj = new AnotherObj();
        // setup fields for obj...

        MyObj mockedObj =     FinalClassWithStaticMethod.staticMethod(obj); // This returns the mocked value.
        // TestUtil.staticMethod calls another class' method which calls FinalClassWithStaticMethod.staticMethod.
        MyObj myObj = TestUtil.staticMethod(obj); // This does not return mocked value.
    }
}
void test() {
    ServiceClient mockedClient = mock(ServiceClient.class);
    // Setup mocks to return as required
    CallsService caller = new CallsService(mockedClient);
}
我的问题是:

单元测试是否适用于此类场景


有没有一种方法可以让这个单元测试在不修改最终类的情况下运行?如果我必须修改现有的类,那么通过最小化对依赖代码的影响,正确的方法是什么?尽管这是一个特定的场景,但链接到展示这种重构的示例将非常有帮助。

在您的情况下,理想情况下应该模拟服务对象。只有当调用服务的方法正在使用模拟对象时,模拟才会起作用。如果在单元测试中创建对象时,可以创建服务的客户机并将其传递给直接从单元测试(setter/constructor)调用服务的类,那么您不必做太多更改

示例代码:

class CallsService {
    public CallsService(final ServiceClient client) {
    ... }
    public someMethod() {
        client.callService();
    }
}
单元测试中:

@RunWith(PowerMockRunner.class)
@PrepareForTest(FinalClassWithStaticMethod.class)
public class MyObjTestCase {
    @Test public void myRandomTest() throws Exception {
        PowerMockito.mockStatic(FinalClassWithStaticMethod.class);
        MyObj returnObj = new MyObj();
        // setup fields for returnObj
        ...
        ...
        PowerMockito.when(FinalClassWithStaticMethod.staticMethod((AnotherObj)anyObject())).thenReturn(returnObj);
        AnotherObj obj = new AnotherObj();
        // setup fields for obj...

        MyObj mockedObj =     FinalClassWithStaticMethod.staticMethod(obj); // This returns the mocked value.
        // TestUtil.staticMethod calls another class' method which calls FinalClassWithStaticMethod.staticMethod.
        MyObj myObj = TestUtil.staticMethod(obj); // This does not return mocked value.
    }
}
void test() {
    ServiceClient mockedClient = mock(ServiceClient.class);
    // Setup mocks to return as required
    CallsService caller = new CallsService(mockedClient);
}
通过这种方式,调用方将在单元测试中使用mockedClient,并且在实际程序中,调用方可以将客户端连接到实际服务