Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to unit-test an internet protocol implementation?
    text
    copied!<p>I decided to add unit tests to my project and continue development in a test-driven kind of way. I’m currently working on implementing unit tests for my ManageSieve client object and I’m not sure what’s the best way to test that beast.</p> <p>My <code>SieveClient</code> object relies on two other objects for the network communication: <code>CocoaAsyncSocket</code> and my own <code>SaslConn</code> object, which is my wrapper around the Cyrus SASL library to handle the authentication methods. For testing I need to replace those with mock objects. I’m going to use the OCMock framework for this. I’m not quite sure how to do this, since the SieveClient object needs to create those objects itself. Right now I overwrite the (private) setters for that object to always install my mock objects using OCMocks <code>partialMockForObject:</code> method. But this feels not right to me. Any ideas how this could be solved better?</p> <p>The other part I have trouble with is the socket itself. To be able to test the protocol details I’d need a way to return predefined test data from the socket. I suppose I could just use OCMock mechanisms to fake the return values from the socket. But since <code>CocoaAsyncSocket</code> provides many different methods to read data from the socket I have to know exactly which are being used by the protocol object in which order. I don’t want my unit test to be that dependent on implementation details of my protocol object. So what should I do here? Implement a mock object for the socket class by hand? This seems non-trivial, so I’d probably need unit tests for that too. Is that a good idea?</p> <p>I’ve read that if something is hard to test it’s probably not very well designed either. But I don’t see how I could do better, since the hard part lies in interacting with the socket which I have to do.</p> <p>If you’d like to see code you can find it at Bitbucket: <a href="https://bitbucket.org/dergraf83/sieve/src/tip/Source/Sieve%20Protocol%20Client/SieveClient.m" rel="nofollow noreferrer">SieveClient.m</a> and <a href="https://bitbucket.org/dergraf83/sieve/src/tip/Source/Sieve%20Protocol%20Client/SieveClient.h" rel="nofollow noreferrer">SieveClient.h</a></p> <h2>Edit: Dependency Injection</h2> <p>So I read about Dependency Injection, and I think I’m going to use this to get the <code>AsyncSocket</code> and <code>SaslConn</code> objects into my <code>SieveClient</code> object. I’ll change my constructor to accept those objects and use them. Since the user of this class usually doesn’t care about the socket and the SASL object I’ll add a factory method (in the form of a convenience constructor) that just creates those objects and passes them to the constructor.</p> <p>But this solves only the first (and easier) part of my testing problem. </p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload