How can I use unit test iOS controllers?

How can I use unit test my view controllers (subclasses of UIViewController) in an iOS application?

I have searched this topic many times over the past few days, but I still cannot figure out what the correct way is.

It seems that there are at least three ways of a logical controller testing controller:

  • Open the personal actions and IBOutlets that you want to use unit test (declare them in the header file).

  • Use a category, such as Tests , to access private activities and IBOutlets from unit tests.

  • Do not expose anything, instead find buttons and other views by name or other public property and simulate user interaction using public UIView methods (for example, simulate a user by clicking a button); then observe the apparent state.

    I have not found many sources on this, but there is an example on objc.io.

Now, to be honest, I don’t like the first two, because, as I understand it, unit tests should not check the internal objects of an object (i.e. private methods) and declare them public only for the sake of tests, It seems to be the best practice. I usually keep IBActions and IBOutlets inside the implementation, but now I suddenly need to make everything public just because I add tests ...

I think there may be another alternative: move as much logic as I can from my view controllers to independent components and test them (leaving the controllers unchecked or mostly unchecked). This seems like a good idea, but I will have to do a lot of refactoring (I am currently adding unit tests for a project that has not been coded for testing).

So, I was wondering what is the best way to test view controllers?

+5
source share
1 answer

This question can be mainly opinion based and should be closed, but I will post some of my opinions anyway.

IBAction and IBOutlet are not a private method / property. You can declare them as a private method / property, but conceptually they represent the open interface of your controller. This is a way to communicate with ideas. Therefore, I will prefer the second option, using a category, such as UI , to access private actions and IBOutlets from unit tests.

I am completely against the third version of unit tests. Because by definition you are writing an integration test, not a unit test. It relies heavily on implementation details and can break easily. You may want a few of them, but you must do unit tests first.

The real solution, as you already know, is to reorganize the code to make it verifiable. Ideally, the controller should be very small and only act as a binding between the view and the models. If you have a very large controller, you must reorganize the user interface logic into a presentation / presentation model and the business logic into a model / model assistant.

+3
source

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


All Articles