Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Some verification involving block methods and OCMockito

I'm using OCMockito and I want to test a method in my ViewController that uses a NetworkFetcher object and a block:

- (void)reloadTableViewContents
{
    [self.networkFetcher fetchInfo:^(NSArray *result, BOOL success) {
        if (success) {
            self.model = result;
            [self.tableView reloadData];
        }
    }];
}

In particular, I'd want to mock fetchInfo: so that it returns a dummy result array without hitting the network, and verify that the reloadData method was invoked on the UITableView and the model is what it should be.

As this code is asynchronous, I assume that I should somehow capture the block and invoke it manually from my tests.

How can I accomplish this?

like image 345
Juan Herrero Diaz Avatar asked May 25 '14 21:05

Juan Herrero Diaz


1 Answers

This is quite easy:

- (void) testDataWasReloadAfterInfoFetched 
{
    NetworkFetcher mockedFetcher = mock([NetowrkFetcher class]);
    sut.networkFetcher = mockedFetcher;

    UITableView mockedTable = mock([UITableView class]);
    sut.tableView = mockedTable;

    [sut reloadTableViewContents];

    MKTArgumentCaptor captor = [MKTArgumentCaptor new];
    [verify(mockedFetcher) fetchInfo:[captor capture]];

    void (^callback)(NSArray*, BOOL success) = [captor value];

    NSArray* result = [NSArray new];
    callback(result, YES);

    assertThat(sut.model, equalTo(result));
    [verify(mockedTable) reloadData];
}

I put everything in one test method but moving creation of mockedFetcher and mockedTable to setUp will save you lines of similar code in other tests.

like image 94
Eugen Martynov Avatar answered Oct 10 '22 08:10

Eugen Martynov