2015-03-18 92 views
0

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

我的问题:

甚至意味着这些场景的单元测试?

有没有办法让我的单元测试在没有修改最终课程的情况下工作?如果我不得不修改现有类,那么对相关代码的影响最小的正确方法是什么?虽然这是一个特定的场景,但是链接到展示这种重构的例子将会很有帮助。

回答

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在单元测试,并在实际的程序就可以得到一个客户端到真正的服务。