Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing sockets

Greetings Stackoverflowers,

I have an application in which a communication abstraction layer exists. Each implementation in this layer, called a connector, provides my application with a way of exchanging data with a connected peer (e.g.: through HTTP, TCP sockets, UDP sockets, etc.).

Per example, I have a Connector_Tcp class that implements methods such as read, write, open and close.

I need to write a unit test for that class. I know that unit tests should have as less dependencies as possible. Unfortunately, in that case, the dependency is a system resource: a socket; and I cannot bypass it.

I need some advice on how to go about unit testing this class.

In my opinion, even though this class is using a system resource, it should be tested as all the other connectors to make sure that it respects the standard established by my application.

I am concerned about such things as binding collisions (Address already in use errors) and blocking. I don't want the unit test to fail because the port is already in use by a system service that has nothing to do with my application.

I have done a lot of unit tests in my days, but none of which relies on such a low-level resource that are sockets.

How would you go about unit testing a socket-dependent class? Open a socket for every unit? Use a single server class, then a manually-defined socket resource to connect to it and test it...?

I guess my problem really is the following:

If the unit test fails... how do I know if:

  • The socket is already in use by another process;
  • The unit test is badly written; or
  • The method behaves improperly (which is what a unit test is worth).

I need the unit test to test only if the method has been behaving properly or not...

like image 642
netcoder Avatar asked Dec 28 '10 05:12

netcoder


People also ask

How do you test a socket?

Turn the power off to the socket. Test the socket by attaching the clip of the continuity tester to the hot screw terminal, the black wire lead. Then, touch the probe to the metal tab in the bottom of the socket. The tester should glow.

What is unit testing with real life example?

An example of a real-world scenario that could be covered by a unit test is a checking that your car door can be unlocked, where you test that the door is unlocked using your car key, but it is not unlocked using your house key, garage door remote, or your neighbour's (who happen to have the same car as you) key.

What should be included in a unit test?

A unit test typically features three different phases: Arrange, Act, and Assert (sometimes referred to as AAA). For a unit test to be successful, the resulting behavior in all three phases must be in line with expectations.

What is unit testing give example?

Unit testing is testing the smallest testable unit of an application. It is done during the coding phase by the developers. To perform unit testing, a developer writes a piece of code (unit tests) to verify the code to be tested (unit) is correct.


1 Answers

I've written a similar abstraction layer, albeit in C/C++, and I have had occasion to unit-test the socket based code. I don't know if there's anything inherently specific to PHP here, so I'll just offer what generic advice I can.

  • Create a server socket in your setup, close it in the tear down. Depending on whether you support many clients connecting to the server socket, you may want to do that part in the test method.
  • Assuming you can specify the port to connect to in your client code, have the server socket bind to port 0 (ephemeral port), and then use this in the client code. This will eliminate the problem of binding to a port already in use.
  • Set timeouts on your sockets. If your test fails for some unexpected reason, you don't want it hanging waiting for a connection forever.
  • You need to be able to interleave the client/server behaviour. For example, you'll want to test what happens if the server shuts down its side of the connection half way through a client read/write. Either asynchronous I/O or multi-threading will do the job. I'm not sure what you have at your disposal in PHP.
like image 122
axw Avatar answered Oct 19 '22 08:10

axw