0

I am trying to test this code with 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();
}   

I can't run this in a unit test, as the system will exit. The initiateShutdown() method does a System.exit();. I have mocked this class with:

@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();
}

I can't do the assertion like this, as r will always be null. Is there any way to assert the response or do I just have to leave out assertions for this test?

eeijlar
  • 1,232
  • 3
  • 20
  • 53
  • What do you want to test? You can test your mock, that makes no sense. If you want to test your method, you need to run it. And that means you need to run your thread... If you want to test this method property, you need to refactor that. – Tunaki Mar 09 '16 at 16:15
  • http://stackoverflow.com/questions/9841623/mockito-how-to-verify-method-was-called-on-an-object-created-within-a-method – Tim B Mar 09 '16 at 16:16
  • You have two mocks, then you call a method on one of these mocks. And... Erm... What exactly are you doing there? You are putting to two mocks in the ring and let them fight it out who can fake it better? What exactly do you think you are testing there, without any actual Object to test... And yes, people are right, you need to refactor that code. – Florian Schaetz Mar 09 '16 at 21:35

1 Answers1

2

Make Slave as an interface. Create 2 implementations of it: e.g. RealSlave and MockSlave. Use RealSlave instance in your real system and MockSlave in tests. While calling MockSlave#initiateShutdown() in tests do nothing but check the method was really called.

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

With this approach you'll be sure your killServer interacts with Slave implementation in proper way. Obviously you current implementation should be reworking to use this idea with Slave interface.

Andriy Kryvtsun
  • 3,220
  • 3
  • 27
  • 41