Doz
Doz

Reputation: 7149

How to test delegates asynchronously with Kiwi

H guys, I have been trying for ages to find some good examples on how to use Kiwi testing to test delegate methods, asynchronously.

I have a manager class that defines the protocols for testing, with a pass and fail method returned in the delegate. Can anyone provide sample code on how to do this? Can I make the test class itself implement the to call the methods on the manager?

Thanks guys

Upvotes: 5

Views: 3183

Answers (2)

Igor
Igor

Reputation: 4207

You can do like in example

 SPEC_BEGIN(IFStackOverflowRequestSpec)

describe(@"IFStackOverflowRequestSpec", ^
{
    context(@"question request", ^
    {
        __block IFViewController *controller = nil;

         beforeEach(^
         {
             controller = [IFViewController mock];
         });

        it(@"should conform StackOverflowRequestDelegate protocol", ^
        {
             [[controller should] conformToProtocol:@protocol(StackOverflowRequestDelegate)];
        });

         it(@"should recieve receivedJSON", ^
         {
             NSString *questionsUrlString = @"http://api.stackoverflow.com/1.1/search?tagged=iphone&pagesize=20";

             IFStackOverflowRequest *request = [[IFStackOverflowRequest alloc] initWithDelegate:controller urlString:questionsUrlString];
             [[request fetchQestions] start];
             [[[controller shouldEventuallyBeforeTimingOutAfter(3)] receive] receivedJSON:any()];
         });

         it(@"should recieve fetchFailedWithError", ^
         {
             NSString *fakeUrl = @"asda";
             IFStackOverflowRequest *request = [[IFStackOverflowRequest alloc] initWithDelegate:controller urlString:fakeUrl];
             [[request fetchQestions] start];
             [[[controller shouldEventuallyBeforeTimingOutAfter(1)] receive] fetchFailedWithError:any()];
         });
    });
});

Full example can be founded on this link.

Upvotes: 6

TimD
TimD

Reputation: 8522

You can do what I think you're trying to achieve by creating a mock object that stands in for the delegate, and then checking that the mock object receives the delegate callbacks that you expect. So the process would look like:

  • create a mock object that conforms to the delegate protocol:

id delegateMock = [KWMock mockForProtocol:@protocol(YourProtocol)];

  • set the mock as the delegate of your manager class:

[manager setDelegate:delegateMock];

  • create an object containing the data that will be returned by your manager class:

NSString *response = @"foo";

  • set the assertion that the mock should eventually be called with the method and response object (in this case, I'm expecting to receive managerRepliedWithResponse and foo)

[[[delegateMock shouldEventually] receive] managerRepliedWithResponse:response];

  • call the method under test:

[manager performMyMethod];

The key is setting the expectation before you call the method, and using shouldEventually which delays the assertion being checked and gives the manager object time to perform the method.

There's a range of expectations you can also use that are listed on the Kiwi wiki - https://github.com/allending/Kiwi/wiki/Expectations

I've written the process up in more detail in a post on my site, albeit that it's more specifically geared-up to the situation I was dealing with.

Upvotes: 4

Related Questions