2016-03-09 60 views
0
的Mockito

我想测试这个代码的Mockito:我怎么能断言就返回嘲笑的对象与

@Override 
public Response killServer() { 
    new Thread(new Runnable() { 
     @Override 
     public void run() { 
      Slave slave = SlaveRunner.getSlave(); 
      slave.initiateShutdown(); 
     } 
    }).start(); 
    String host = System.getenv("HOSTNAME"); 
    return Response.ok().entity(new String ("Stopping REST service on " + host)).build(); 
} 

在一个单元测试,我不能运行这个,因为系统会退出。 initiateShutdown()方法执行System.exit();。我嘲笑这个类:

@Test 
public void killServer() throws RestInterfaceException { 
    SlaveRestInterface mockedAgent = Mockito.mock(SlaveRemoteProxy.class); 
    Response r = Mockito.mock(Response.class);  
    Mockito.when(mockedAgent.killServer()).thenReturn(r); 
    Assert.assertEquals(r.readEntity(String.class), "Stopping REST service on " + System.getenv("HOSTNAME")); 
    r.close(); 
} 

我不能这样断言,因为r将永远为空。有没有什么方法可以断言这个答案呢,还是我不得不忽略这个测试的断言?

+0

你想测试什么?你可以测试你的模拟,这是没有意义的。如果你想测试你的方法,你需要运行它。这意味着你需要运行你的线程......如果你想测试这个方法属性,你需要重构它。 – Tunaki

+0

http://stackoverflow.com/questions/9841623/mockito-how-to-verify-method-was-called-on-an-object-created-within-a-method –

+0

你有两个嘲笑,然后你打电话给方法在这些模拟之一。而......呃......你到底在做什么?你在戒指中放两个嘲讽,让他们去争取谁能更好地伪装它?你认为你在那里测试什么,没有任何实际的对象来测试......是的,人们是对的,你需要重构那些代码。 –

回答

1

Slave作为接口。创建它的2个实现:例如RealSlaveMockSlave。在实际系统中使用RealSlave实例,在测试中使用MockSlave。在测试中调用MockSlave#initiateShutdown()时,除了检查方法是否真的被调用之外什么也不做。

Slave slave = Mockito.mock(Slave.class); 
Mockito.doNothing().when(slave).initiateShutdown(); 
... 
initiate `killServer` call somehow 
... 
Mockito.verify(slave).initiateShutdown(); 

通过这种方法你就可以确保你的killServer以适当的方式执行Slave互动。很明显,您当前的实施应该重新设计,以便与Slave界面一起使用此想法。