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

时间:2015-03-18 23:59:32

标签: java unit-testing mockito powermock

我有一个单元测试失败,因为它间接调用依赖于服务的方法。但是,在运行单元测试时,服务处于脱机状态。我尝试使用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.
    }
}

我的问题:

单元测试是否适用于此类情况?

有没有办法让我可以在不修改最终课程的情况下让这个单元测试工作?如果我必须修改现有的类,通过对依赖代码的最小影响来实现它的正确方法是什么?虽然这是一个特定的场景,但是展示这种重构的示例的链接将是很有帮助的。

1 个答案:

答案 0 :(得分:0)

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

示例代码:

class CallsService {
    public CallsService(final ServiceClient client) {
    ... }
    public someMethod() {
        client.callService();
    }
}

在单元测试中:

void test() {
    ServiceClient mockedClient = mock(ServiceClient.class);
    // Setup mocks to return as required
    CallsService caller = new CallsService(mockedClient);
}

这样调用者将在单元测试中使用mockedClient,而在实际程序中,它可以使客户端获得真实服务。