How to unit test the client network code?

I am working on network code that listens for a TCP connection, parses incoming data, and raises the corresponding event. Naturally, to avoid blocking the rest of the application, listening and parsing are performed in the background worker. When I tried the unit test of this code, I ran into the problem that, seeing that the network code has more work than the unit test, the unit test ends before the adapter has the opportunity to raise an event, and therefore the test fails.

Adapter Class:

public class NetworkAdapter : NetworkAdapterBase //NetworkAdapterBase is just an abstract base class with event definitions and protected Raise... methods. { //Fields removed for brevity. public NetworkAdapter(TcpClient tcpClient) { _tcpConnection = tcpClient; //Hook up event handlers for background worker. NetworkWorker.DoWork += NetworkWorker_DoWork; if (IsConnected) { //Start up background worker. NetworkWorker.RunWorkerAsync(); } } private void NetworkWorker_DoWork(object sender, DoWorkEventArgs e) { while (IsConnected) { //Listen for incoming data, parse, raise events... } } } 

Test code attempt:

 [TestMethod] public void _processes_network_data() { bool newConfigurationReceived = false; var adapter = new NetworkAdapter(TestClient); //TestClient is just a TcpClient that is set up in a [TestInitialize] method. adapter.ConfigurationDataReceived += (sender, config) => { newConfigurationReceived = true; }; //Send fake byte packets to TestClient. Assert.IsTrue(newConfigurationReceived, "Results: Event not raised."); } 

How should I try to verify this?

Thanks,

James

+4
source share
4 answers

Well, firstly, this is not a strict "unit test"; your test depends on architecture levels that have side effects, in which case they transmit network packets. It is rather an integration test.

However, your unit test can sleep for a certain number of milliseconds, as Tony said. You can also see if you can get the background worker descriptor and join it, which will cause your unit test to wait for the background worker to finish the job.

+6
source

You can wait a while, and then run this statement:

 //Send fake byte packets to TestClient Thread.Sleep(TIMEOUT); Assert.IsTrue(newConfigurationReceived, "Results: Event not raised."); 

Where TIMEOUT is the number of milliseconds you want to wait.

+2
source

You can use some timeout, but as always, how long should the timeout be to ensure that you will always pass the test, but still not slow down your tests too much?

I would just check the code parsing. This is probably the place where you will have most errors, and where you most need unit tests. And it's just a check!

Then for the code that listens on the socket ... well, you might have errors here ... but if it just sends data to a function / class, I'm not sure if you really need to test it. And if you want to be very thorough, how are you going to unit test, that your class behaves well if the connection is lost between the client and server, for example?

+2
source

In our unit tests, we use the .NET 4 distribution library. You can say:

 Parallel.Invoke(() => Dosomething(arguments), () => DosomethingElse(arguments)); 

And the structure will take care to create these actions as different threads, executing them in several threads, ideally suited for the specific processes you are working on, and then attach them so that the next instruction will not be executed until they are all over .

However, it looks like you might have direct access to the stream. Instead, you want to wait until this callback method is called. You can use AutoResetEvent or ManualResetEvent for this.

See Asynchronous Device Test Function

+2
source

Source: https://habr.com/ru/post/1341846/


All Articles