Capturing blocks from method parameters in Kiwi?

471 Views Asked by At

I'm working with the Firebase iOS SDK, and I'm struggling to figure out how to fully-test some of the Firebase method calls using Kiwi.

I'm using an instance of Firebase to "watch" a path:

Firebase *streamsReference = [self.firebaseRef childByAppendingPath:@"streams"];

And then using that streamsReference to observe events:

[streamsReference observeEventType:FEventTypeChildAdded withBlock:^(FDataSnapshot *snapshot) {

    // do stuff in the block here

}];

I want to test the effects of the code in the block.

This is what I've got so far:

    it(@"should handle incoming connections as a hook for WebRTC", ^{

        id mockFirebaseClass = [KWMock mockForClass:[Firebase class]];

        // mock Firebase object to handle "/streams" path
        id mockFirebaseStreamsReference = [KWMock mockForClass:[Firebase class]];

        // return the streams reference object via the mock Firebase object
        [mockFirebaseClass stub:@selector(childByAppendingPath:) andReturn:mockFirebaseStreamsReference];

        // attempt to capture the block in the second param
        KWCaptureSpy *spy = [mockFirebaseStreamsReference captureArgument:@selector(observeEventType:withBlock:) atIndex:1];

        // inject the Firebase mock into the test class
        classUnderTest.firebaseRef = mockFirebaseClass;

        // capture the block from the spy
        void(^blockToRun)() = spy.argument;

        // call method that will invoke the Firebase observeEventType:withBlock method
        [classUnderTest setupIncomingRemoteConnectionHandler];

        //  run the captured block
        blockToRun(nil);

        ...
        ... expectations go here
        ...

    });

When I run the test, it's failing with an Argument requested has yet to be captured error - which suggests that I'm nailing things up in the wrong order. Can anyone see where I'm going wrong here?

1

There are 1 best solutions below

0
On

You are trying to capture the argument too early, before the watched method had been called. Try to move the void(^blockToRun)() = spy.argument; line after the call to setupIncomingRemoteConnectionHandler. If that doesn't work either, it means that you need make run some extra calls to your test class in order to trigger the observeEventType:withBlock: call.