Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<blockquote> <p>But then I rejected the idea, because it wouldn’t help very much. I could test the SieveClient object more easily, true. But then I’d have the same problems with testing the new object. Seems to me that this is just putting up the trouble for later. Especially since I have nothing I could re-use the new class for.</p> </blockquote> <p>It wouldn't be the same problem.</p> <p>I'll assume you need SieveClient to control the instantiation of the other objects internally because its part of an API you don't want to expose. If that's the reason, by separating them, you no longer have the same need, since you can have <strong>the SieveClient control the bindings and the other part</strong> that does the protocol <strong>receives the instances it'll work with</strong>.</p> <p>By doing the above, you can <strong>hand over the mocked objects to your protocol implementation</strong>. <strong>Those mocks would then have any expectations you may need</strong>. If you find it you end up with it being too involved, then you probably need to refocus responsibilities, which usually results in a cleaner/simpler protocol implementation anyway (if you find that you need to from doing those unit tests).</p> <p>Above said, you also need to <strong>consider if the code you are trying to test is as focused as possible on the protocol and doesn't have any extra elements. If that's the case, it wouldn't be a good candidate to unit test it, as its sole responsibility is the interaction with an external system. I'd decide how important is the protocol spec in this system, and if its all about integration with an external system I'd treat it like a focused integration test instead that hits the real external system and is kept separated from the unit tests</strong> (so it doesn't affects the speed needed to run unit tests of the rest of the system).</p> <hr> <p>After re-reading the question because of the edit, I have to stress out what I said about <strong>focused integration tests</strong> above. You ask:</p> <blockquote> <p>But since CocoaAsyncSocket 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> </blockquote> <p>If you are dealing with a very complex object and that object is all about integration beyond a boundary, you usually are best avoiding it as part of unit tests. In that scenario you want a focused integration test / to hit the real external system. <strong>This doesn't mean all the unit tests of the rest of your code, hit the external system, just the very simple unit of code/class that uses that object</strong>. </p> <p><strong>It may very well be the case that such object is SieveClient in your scenario, in that case forget about unit tests of that piece of the code. What you want to do instead is mock the SieveClient when testing code that uses it. On the other hand, if you find that SieveClient is much more than that, you want to add a class that simplifies these communication aspects, and that'd be what you mock when testing SieveClient and also what you do a focused integration test against.</strong></p> <p>This type of tests are a very effective way to make sure that the code that interacts with the external is working as expected, since that's the focus of both the class and the tests involved. <strong>In case something on the external system starts working differently, you notice it clearly - as opposed to having it mixed with your application logic or worst not tested at all.</strong></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