2015年8月11日 星期二

Mock completion block with OCMock

This is an example unit test using Specta, Expecta and OCMock.
Another example - WordPress iOS app unit test.

#import "Specta.h"
#define EXP_SHORTHAND
#import "Expecta.h"
#import <OCMock/OCMock.h>
#import "RoomListViewModel.h"
#import <EXTScope.h>

SpecBegin(RoomListViewModel)

describe(@"RoomListViewModel", ^{

    __block RoomListViewModel *viewModel;
    __block id home;
    __block id room;

    beforeAll(^{

    });

    beforeEach(^{
        home = OCMClassMock([HMHome class]);
        room = OCMClassMock([HMRoom class]);
        viewModel = [[RoomListViewModel alloc] initWithHome:home];
    });

    it(@"add room with name", ^{
        OCMStub([home addRoomWithName:OCMOCK_ANY completionHandler:OCMOCK_ANY]).andDo(^(NSInvocation *invocation) {
            void(^ __unsafe_unretained completionHandler)(HMRoom *room, NSError *error);
            [invocation getArgument:&completionHandler atIndex:3];
            completionHandler(room, nil);
        });    
        waitUntil(^(DoneCallback done) {
            @weakify(viewModel);
            [viewModel addRoomWithName:@"test" completionHandler:^(NSError *error) {
                @strongify(viewModel);
                expect(...);
                done();
            }];
        });

    });  

    afterEach(^{
        viewModel = nil;
    });

    afterAll(^{

    });
});

SpecEnd
void(^ __unsafe_unretained completionHandler)(HMRoom *room, NSError *error);

Why declare our block __unsafe_unretained?
See http://stackoverflow.com/a/13831074/1060971, Carl Lindberg’s comment.

[invocation getArgument:&completionHandler atIndex:3];

In NSInvocation, argument index 0 is self , index 1 is cmd.
First argument of addRoomWithName is at index 2, completion block argument is at index 3.
So, assign our mock block at index 3.

2015年8月6日 星期四

Xcode6 + Swift 1.2 Podfile

Swift 1.2 + RAC3

platform :ios, "8.0"
use_frameworks!

pod "ReactiveCocoa", '3.0-RC.1'

target :MyAppTests, :exclusive => true do
  pod 'Quick', '0.3.1'
  pod 'Nimble', '1.0.0'
end