Why is taunting with DI better than mocking objects in objective-c?

this blog article reads:

Although there are sometimes reasonable ways to mock objects without a DI (usually by mocking class methods, as seen in the OCMock example above), it often fails. Even when possible, the complexity of the test setup can outweigh the benefits. If youre using dependency consistently, you will find writing tests using stubs and layouts will be much easier.

but that doesn’t explain why. What are the possible scenarios in which DI (injecting an id object that matches the protocol) will play better in Objective-C than a simple OCMockito:

 [given([mockArray objectAtIndex:0]) willReturn:@"first"]; [verifyCount(mockArray, times(1)) objectAtIndex:]; 

?

+7
dependency-injection ios objective-c unit-testing mocking
source share
4 answers

I noticed that it is easier to create a separate class for a test purpose when the source class performs some asynchronous actions.

Suppose you are writing a test for a UIViewController that has a LoginSystem dependency that uses AFNetworking to execute an API request. LoginSystem takes a block argument as a callback. (UIViewController-> LoginSystem-> AFNetworking).

If you are mistaken in the LoginSystem, you may have problems with how to start the callback block to check if the UIViewController is successful / failed. When I tried, I ended up with MKTArgumentCaptor to get a block argument, and then I had to call it in a test file.

On the other hand, if you create a separate class for LoginSystem (call it LoginSystemStub, which extends from LoginSystem), you can make fun of the behavior in three lines of code and outside the test file. We must also keep the test file clean and readable.

Another thing is that verify () does not work with checking asynchronous behavior. It is much easier to call expect (smth2). will be .equal (smth)

EDIT:

Pointers to NSError (NSError **) also work poorly with verify (), and it is better to create a stub: D

+1
source share

Imagine trying to test the more complex behavior of an object interacting with one of its children. To make sure that the parent object is working correctly, you must make fun of all the methods of the child object and even potentially track its changing state.

But if you do, you just wrote a brand new object in a confusing and confusing way. It would be easier to write a completely new object and tell parents to use it.

0
source share

With DI, you enter your model at runtime; it is not bound in your classes, but only in the configuration.
When you want to taunt, you simply create a model of the model and enter it instead of your real data. In addition to the model, you have changed your implementation in one line.

See here for an example or here for an idea of ​​it.

Disclaimer: Of course, you can make fun of other things besides the model, but this is probably the most common use case.

0
source share

Answer: This is not better. This is only better if you need some kind of super-standard behavior.

The best thing about this is that you do not need to create an interface / protocol for each class you enter, and you can limit the DIs that you really need to make your code cleaner and more YAGNI.

This applies to any dynamic or reflection language. Making so much mess just for Unit-Tests seemed like a bad idea to me.

0
source share

All Articles