How do I unit test iOS view controllers?

iosdude

How am I supposed to unit test my view controllers (UIViewController subclasses) in an iOS app?

I've been extensively googling this subject for the last couple of days but I still can't understand what is the proper way of doing this.

It seems that there are at least three ways of unit testing view controller logic:

  • Expose private actions and IBOutlets that you want to unit test (declare them in the header file).

  • Use a category, like Tests, to access private actions and IBOutlets from unit tests.

  • Don't expose anything, instead find buttons and other views by title or another public property and simulate user interaction via public UIView methods (e.g. simulate user tapping a button); then observe visible state.

    I didn't find a lot of sources on this one, but there is an example on objc.io.

Now, to be honest, I don't really like the first two because as far as I understand unit tests are not supposed to test object's internals (i.e. private methods), and declaring them public only for the sake of tests doesn't seem like the best practice. I usually keep IBActions and IBOutlets inside the implementation but now I suddenly have to make everything public only because I'm adding tests...

I think there might be another alternative: move as much logic as I can from my view controllers into independent components and test them instead (leaving controllers untested or mostly untested). This seems like a nice idea but I'll have to do lots of refactoring (I'm currently adding unit tests for a project that wasn't coded with testing in mind).

So I was wondering, what is the best way of testing view controllers?

Bryan Chen

This is question may be primarily opinion-based and should be closed but I will post some of my opinions anyway.

IBAction and IBOutlet are not really private method/property. You may be able to declare them as private method/property but conceptually they are the public interface of you view controller. They are the way to communicate with views. Therefore, I will prefer the second way, use a category, like UI, to access private actions and IBOutlets from unit tests.

I totally against the third way for unit tests. Because by definition, you are writing integration test rather than unit test. It heavily rely on implementation details and can breaks easily. You may want a few of them but you should get unit tests done first.

The real solution, as you already aware, is to refactor the code to make them testable. Ideally, controller should be very small and only acts as the binding between view and models. If you have very large controller, you should refactor UI logic into view/view model and business logic in to model/model helper.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

How do I unit test Android code that has View Animators?

From Dev

How do I expose private properties in an iOS unit test?

From Dev

How do I create an array of View Controllers?

From Dev

Asserting view with Grails Spock Unit Test for Controllers

From Dev

How to do unit test in IOS using XCode?

From Dev

How do I show two view controllers in a single view?

From Dev

How do I setup a Unit Test for Swift?

From Dev

How do I Unit Test Runnable Class?

From Dev

How do I unit test a filter?

From Dev

How do I unit test django urls?

From Dev

Android Unit Testing : How do I test this?

From Dev

How do I mock controller context in my unit test so that my partial view to string function works?

From Dev

How do I mock controller context in my unit test so that my partial view to string function works?

From Dev

SailsJS: How to properly unit test controllers?

From Dev

IOS -NSRunLoop in XCTest: How Do I Get A Run Loop to Work in A Unit Test?

From Dev

How do I test the logger output using Test::Unit in Rails?

From Dev

How do I unit test and integration test my SSIS packages?

From Dev

How do I test the logger output using Test::Unit in Rails?

From Dev

How do you unit test ASP.NET Core MVC Controllers that return anonymous objects?

From Dev

How do you unit test ASP.NET Core MVC Controllers that return anonymous objects?

From Dev

How can I start a unit test for this method? iOS

From Dev

How Can I Unit Test Calling of iOS Application Delegate Methods?

From Dev

How do I unit test RecyclerView , LinearLayoutManager in Robolectric?

From Dev

How do I resolve a promise in an AngularJS unit test

From Dev

How do i unit test the auth filter in Laravel 4.1?

From Dev

How do I unit test spring security @PreAuthorize(hasRole)?

From Dev

How do I fail a Node unit test on the catch of a Promise?

From Dev

How do I mock a class in a Python unit test?

From Dev

How do I unit test an AngularJS controller that relies on a promise?

Related Related

  1. 1

    How do I unit test Android code that has View Animators?

  2. 2

    How do I expose private properties in an iOS unit test?

  3. 3

    How do I create an array of View Controllers?

  4. 4

    Asserting view with Grails Spock Unit Test for Controllers

  5. 5

    How to do unit test in IOS using XCode?

  6. 6

    How do I show two view controllers in a single view?

  7. 7

    How do I setup a Unit Test for Swift?

  8. 8

    How do I Unit Test Runnable Class?

  9. 9

    How do I unit test a filter?

  10. 10

    How do I unit test django urls?

  11. 11

    Android Unit Testing : How do I test this?

  12. 12

    How do I mock controller context in my unit test so that my partial view to string function works?

  13. 13

    How do I mock controller context in my unit test so that my partial view to string function works?

  14. 14

    SailsJS: How to properly unit test controllers?

  15. 15

    IOS -NSRunLoop in XCTest: How Do I Get A Run Loop to Work in A Unit Test?

  16. 16

    How do I test the logger output using Test::Unit in Rails?

  17. 17

    How do I unit test and integration test my SSIS packages?

  18. 18

    How do I test the logger output using Test::Unit in Rails?

  19. 19

    How do you unit test ASP.NET Core MVC Controllers that return anonymous objects?

  20. 20

    How do you unit test ASP.NET Core MVC Controllers that return anonymous objects?

  21. 21

    How can I start a unit test for this method? iOS

  22. 22

    How Can I Unit Test Calling of iOS Application Delegate Methods?

  23. 23

    How do I unit test RecyclerView , LinearLayoutManager in Robolectric?

  24. 24

    How do I resolve a promise in an AngularJS unit test

  25. 25

    How do i unit test the auth filter in Laravel 4.1?

  26. 26

    How do I unit test spring security @PreAuthorize(hasRole)?

  27. 27

    How do I fail a Node unit test on the catch of a Promise?

  28. 28

    How do I mock a class in a Python unit test?

  29. 29

    How do I unit test an AngularJS controller that relies on a promise?

HotTag

Archive