HowTo Unit Test Client Server Code

2019-03-17 20:39发布

问题:

I'm currently writing a Java Client Server Application. So i want to implement two Libraries, one for the Client and one for the Server. The Client Server Communication has a very strict protocol, that I wan't to test with JUnit.

As build tool im using Maven and a Husdon Server for continues Integration.

Actually I do not have any good Idea how to test these Client / Server Libraries.

I got following Approaches:

  1. Just write a Dummy Client for testing the server and write a Dummy Server to test the Client. Disadvantages: Unfortunately this will result in many extra work. I could not be 100% sure that client and Server could work together, because I'm not sure that the Tests are completely identical.

  2. Write an separate Test Project that Tests the Client and the Server together.
    Disadvantages: The Unit Tests does not belong to the Project it self, so Hudson will not run them automatically. Everyone who changes anything at one of these Libraries, will have to run the Tests manually to ensure, everything is correct. Also i will not receive any Code Coverage Report.

Are there any better approaches to test codes like that? Maybe test a Maven Multi Module Project, or something like that.

I hope any one got a good solution for that Issue.

Thanks.

回答1:

Think of all your code as "transforms input to output": X -> [A] -> Y

X is the data that goes in, [A] is the transformer, Y is the output. In your case, you have this setup:

[Client] -> X -> [Server] -> Y -> [Client]

So the unit tests work like this:

  1. You need a test that runs the client code to generate X. Verify that the code actually produces X with an assert. X should be a final static String in the code.

  2. Use the constant X in a second test to call the server code which transforms it into Y (another constant).

  3. A third test makes sure that the client code can parse the input Y

This way, you can keep the tests independent and still make sure that the important parts work: The interface between the components.



回答2:

My suggestion would be to use two levels of testing:

  1. For your client/server project, include some mocking in your unit tests to ensure the object interfaces are working as expected.

  2. Following the build, have a more extensive integration test run, with automation to install the compiled client and server on one or more test systems. Then you can ensure that all the particulars of the protocol are tested thoroughly. Have this integration test project triggered on each successful build of the client/server project. You can use JUnit for this and still receive the conventional report from Hudson.



回答3:

So finally the resolution was to build a Multi Module Project, with a separate Test Module that includes the Server and the Client Module Works great in Husdon. And even better in the Eclipse IDE. Thanks @ Aaron for the hint



回答4:

The latest approach to solve this problem is by using Docker containers. Create a docker file containing a base image and all the necessary dependencies required for your client server application. Create a separate container for each node type of your distributed client-server system and test all the entry point server API/client interactions using TestNG or JUnit. The best part of this approach is that you are not mocking any service calls. In most cases you can orchestrate all the end-to-end client-server interactions.

There is a little bit of learning curve involved in this approach but Docker is becoming highly popular in the Dev community especially for solving this problem.

Here is an example of how you could use docker client api to pull docker images in your JUnit test: https://github.com/influxdb/influxdb-java/blob/master/src/test/java/org/influxdb/InfluxDBTest.java



回答5:

You may use any mock object framework to create mock objects - Try jmockit.