ramin
ramin

Reputation: 968

JUnit best practise - testing methods, where the result cannot be verified with public methods

I am writing a Socket Application in Java, where a server is taking messages from an eventsource and sending notifications to connected users, depending on the eventtype.

Now I am about to write some JUnit tests for the Server... JUnit (in eclipse automatically suggests) to implement tests for all public methods and I see the necessity for it. The server class has a public method bufferEvent..., but then the events are handled in private methods and there is not even a method, which returns the number of buffered messages.

So the Server doesn't have public methods to verify the result.

I think the problem can be generalized: How can I test public methods, where the result cannot be verified with public methods( no getter etc.)

I want to avoid writing additional methods just for testing. Is there a workaround, or best practise to test those things?

Thanks in advance

Upvotes: 2

Views: 524

Answers (3)

ramin
ramin

Reputation: 968

What do think about adding a Logger, with it's own Level TEST , loggin important values at the end of the methods and having a stream to A testclass.

Upvotes: 0

Alex
Alex

Reputation: 3013

You should make a constructor that allows you to insert mocks or spies for the collaborators.

For example, you server would have a constructor Server(List<Buffer> buffer). Only used for testing. Then you can add the buffer in the unit test, and assert that modifications are made to that buffer.

List is easy enough to replace with a object you create in the test. If you want more advanced stuff, have a look at a mocking framework like Mockito.

For example you create a mock for a Socket. You'd get Socket = mock(Socket.class. You insert in in the constructor Server(List<Buffer> buffer, Socket socket). Then after you have called whatever function you want to test, you can verify behavior using for example verify(socket).send("yourMessage") to see if the server used the method send with parameters "yourMessage".

For example this Plugins class requires some plugins in it's constructor. To test its the mocks are created, inserted and then verified in this test class like this: verify(proxyServerPlugin).proxyServer(config);.

See the Mockito for more examples.

Upvotes: 2

nano_nano
nano_nano

Reputation: 12523

You could check the negative test case. There is no return from the service but maybe there is an exception which is thrown by the service:

@Test
public void testServerService(){
try{
   myServer.service();
   Assert.assertTrue(true);
}catch(Exception ex){
   Assert.fail("anything goes wrong");
}
}

Otherwise in such cases I write something like this:

@Test
public void testServerService(){
   myServer.service();
   Assert.assertTrue(true);
}

so I have at least on assertion to check if the process runs without problems.

btw I think you are right. writing new functionality just to verify Junit testcases is very bad practice.

Upvotes: 1

Related Questions