0

I'm a beginner in Unit Test and I would like to test my cases in a switch but I don't know how to do it.

I have :

 - (void)testClickSmiley
{
    [self.viewController click:nil];
    // Here What i do ? I use what kind of XCTest Assertions ? I want to test if it goes into "default" for example
}

And in my ViewController :

- (IBAction)click:(id)sender
{
    UIButton *btn = (UIButton *)sender;

    switch (btn.tag) {

        case Bad:
            // Show view Bad
            break;

        case Average:
            // Show view Average
            break;

        case Good:
            // Show view Bad
            break;

        default:
            break;
    }
}

Of course, I don't want to modify my ViewController.

Any ideas ? TY

Aximem
  • 714
  • 8
  • 27

2 Answers2

0

What you actually should be doing in this case is writing UI tests for this scenario. Your context and execution environment do not allow you to test your code based on unit tests (for example, the app is not aware of any button you pass to the test) the way you expect it.

Of course the first thing that is wrong is that you use

[self.viewController click:nil];

The click function will get a nil value for the button and the tag will therefore be nil as well.

Of course you could mock a button:

UIButton *button = [[UIButton alloc] initWith...]
button.tag = [YourEnum].Bad
[self.viewController click: button];

But that would still leave you with the problem that you don't know where the switch ended up going...

Solution (if applicable):

Take a look at UI Testing

https://developer.apple.com/videos/play/wwdc2015/406/

It allows you to run the application and simulate user interactions + you have the benefit that you can always assume you are working with the actual button that caused the click: event in the first place.

the_critic
  • 12,720
  • 19
  • 67
  • 115
0

There is nothing wrong with exercising your view controller in a straight unit test without using UI testing. In fact, I would have more unit tests and fewer UI tests (if any).

Why? It depends on the purpose of your tests. The reason I test is to get fast feedback to enable refactoring and TDD. I need tests that are fast and dependable, not slow and fragile.

So go ahead and write tests that invoke your view controller. To your question, "What do I do here?" You verify the actions that would be taken. For example, you can test

  • Changes to the view
  • Changes to the underlying model
  • Calling the next view controller with the expected data

It's unusual to have a single IBAction method act as a fan-out of multiple actions. This ties them together unnecessarily. A change to a single action could break other actions. Instead, consider creating multiple IBAction methods, one per action.

To see an example of how to write unit tests for a UIViewController — in fact, how to TDD it — see my screencast How to Do UIViewController TDD.

Jon Reid
  • 20,545
  • 2
  • 64
  • 95