erikdoe / ocmock

Mock objects for Objective-C
http://ocmock.org
Apache License 2.0
2.16k stars 606 forks source link

[OCMArg invokeBlockWithArgs:...] doesn't work with protocol mock arguments #329

Closed chritto closed 7 years ago

chritto commented 7 years ago

I love the ability to provide an OCMArg which automagically invokes the provided block, especially given the asynchronous nature of much of our code base. However, providing protocol mocks as the arguments to these blocks crashes within NSInvocation+OCMAdditions.m.

Here is an example which crashes:

- (void)testInvokesBlockWithProtocolMockArgs
{
    id mockProtocol = OCMProtocolMock(@protocol(TestProtocol));
    id mockObject = OCMClassMock([TestClassWithProtocolBlockArgMethod class]);
    [[mockObject stub] doStuffWithBlock:[OCMArg invokeBlockWithArgs:mockProtocol, nil]];

    __block BOOL wasCalled = NO;
    __block id<TestProtocol> firstParam;
    void (^block)(id<TestProtocol> arg) = ^(id<TestProtocol> arg) {
        wasCalled = YES;
        firstParam = arg;
    };
    [mockObject doStuffWithBlock:block];

    XCTAssertTrue(wasCalled, @"Should have invoked block.");
    XCTAssertEqual(firstParam, mockProtocol, @"Param does not match");
}

which crashes because the mockProtocol is a protocol mock. Modifying mockProtocol to be a class mock fixes the crash, and the test passes.

We're using OCMock 3.3.

Console log:

`*** NSForwarding: warning: object 0x61800023b040 of class '__NSMessageBuilder' does not implement doesNotRecognizeSelector: -- abort`.

Full stack trace:

0   ???                                 0x00000001005d26cd 0x0 + 4301072077,
1   xctest                              0x00000001000015e1 xctest + 5601,
2   CoreFoundation                      0x00007fff87a6db08 _CF_forwarding_prep_0 + 120,
3   Foundation                          0x00007fff8954decb -[NSProxy isKindOfClass:] + 64,
4   OCMock                              0x0000000100558f95 -[NSInvocation(OCMAdditions) setArgumentWithObject:atIndex:] + 165,
5   OCMock                              0x0000000100558a60 +[NSInvocation(OCMAdditions) invocationForBlock:withArguments:] + 352,
6   OCMock                              0x000000010056afec -[OCMBlockArgCaller handleArgument:] + 108,
7   OCMock                              0x000000010055cd3d -[OCMInvocationStub handleInvocation:] + 461,
8   OCMock                              0x0000000100562c9c -[OCMockObject handleInvocation:] + 1932,
9   OCMock                              0x0000000100562320 -[OCMockObject forwardInvocation:] + 64,
10  CoreFoundation                      0x00007fff87a6ddaa ___forwarding___ + 538,
11  CoreFoundation                      0x00007fff87a6db08 _CF_forwarding_prep_0 + 120,
12  OCMockTests                         0x000000010514d36a -[OCMockObjectTests testInvokesBlockWithProtocolMockArgs] + 474,
13  CoreFoundation                      0x00007fff87a6f3ec __invoking___ + 140,
14  CoreFoundation                      0x00007fff87a6f271 -[NSInvocation invoke] + 289,
15  XCTest                              0x00000001000acb7e __24-[XCTestCase invokeTest]_block_invoke_2 + 481,
16  XCTest                              0x00000001000e6c3c -[XCTestContext performInScope:] + 190,
17  XCTest                              0x00000001000ac98a -[XCTestCase invokeTest] + 255,
18  XCTest                              0x00000001000ad1a3 -[XCTestCase performTest:] + 457,
19  XCTest                              0x00000001000aa2ac -[XCTestSuite performTest:] + 491,
20  XCTest                              0x00000001000aa2ac -[XCTestSuite performTest:] + 491,
21  XCTest                              0x00000001000aa2ac -[XCTestSuite performTest:] + 491,
22  XCTest                              0x0000000100096cc8 __25-[XCTestDriver _runSuite]_block_invoke + 51,
23  XCTest                              0x00000001000bee7b -[XCTestObservationCenter _observeTestExecutionForBlock:] + 602,
24  XCTest                              0x0000000100096b5d -[XCTestDriver _runSuite] + 438,
25  XCTest                              0x00000001000978b9 -[XCTestDriver _checkForTestManager] + 612,
26  XCTest                              0x00000001000e80ad _XCTestMain + 628,
27  xctest                              0x000000010000174b xctest + 5963,
28  libdyld.dylib                       0x00007fff9cfca255 start + 1
)