How to test delegates asynchronously with Kiwi
Asked Answered
O

2

5

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

Outshine answered 28/11, 2012 at 23:26 Comment(0)
D
6

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.

Dodd answered 15/1, 2013 at 9:2 Comment(0)
I
4

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.

Idempotent answered 5/12, 2012 at 6:8 Comment(2)
+1 for the very subtle but very important detail! "The key is setting the expectation before you call the method"Inhibitor
It's been more that a year now and I am struggling with the same thing. It simply doesn't work, before/after with expectFutureValue/without. The only way I can have the damn this wait for the request to be done is by having a real value to check on somewhere.Corves

© 2022 - 2024 — McMap. All rights reserved.