erikdoe / ocmock

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

Partial mock for private setter method crash #386

Closed CSLMeyers closed 4 years ago

CSLMeyers commented 4 years ago

I used OCPartialMockObject to verify whether some method invoked. such as

id mock = [OCMockObject partialMockForObject:[DataProvider class]];
[mock updateSearchTerm:searchTerm]
[[mock expect] invokedMethod]

In updateSearchTerm method, the test code works well as I expected. But there also has an async block inside updateSearchTerm which is a black box for test code, so I don't know when the block will be invoked. Sometimes when test runs successfully, but async block will call back and crash with the following callstack:

2020-03-05T10:27:06.357Z [E]uncaught exception: -[DataProvider ocmock_replaced_setCurrentSearchTerm:]: unrecognized selector sent to instance 0x60000166a9a0 StackTrace : 
(
    0   CoreFoundation                      0x000000011eb4c6fb __exceptionPreprocess + 331
    1   libobjc.A.dylib                     0x000000011dd7bac5 objc_exception_throw + 48
    2   CoreFoundation                      0x000000011eb6aab4 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132
    3   CoreFoundation                      0x000000011eb51443 ___forwarding___ + 1443
    4   CoreFoundation                      0x000000011eb53238 _CF_forwarding_prep_0 + 120
    5   CoreFoundation                      0x000000011eb534cc __invoking___ + 140
    6   CoreFoundation                      0x000000011eb50a45 -[NSInvocation invoke] + 325
    7   OCMock                              0x000000013dda4ba8 -[OCPartialMockObject forwardInvocationForRealObject:] + 216
    8   CoreFoundation                      0x000000011eb511a1 ___forwarding___ + 769
    9   CoreFoundation                      0x000000011eb53238 _CF_forwarding_prep_0 + 120
    10  HostApp                             0x00000001065c5ddb __54-[DataProvider updateSearchTerm:traceInfo:]_block_invoke + 235
    11  libdispatch.dylib                   0x0000000120b3accf _dispatch_call_block_and_release + 12
    12  libdispatch.dylib                   0x0000000120b3bd02 _dispatch_client_callout + 8
    13  libdispatch.dylib                   0x0000000120b42720 _dispatch_lane_serial_drain + 705
    14  libdispatch.dylib                   0x0000000120b43261 _dispatch_lane_invoke + 398
    15  libdispatch.dylib                   0x0000000120b4bfcb _dispatch_workloop_worker_thread + 645
    16  libsystem_pthread.dylib             0x0000000120f18611 _pthread_wqthread + 421
    17  libsystem_pthread.dylib             0x0000000120f183fd start_wqthread + 13
) AXPContext:788

currentSearchTerm is a private property of DataProvider. it random fails and I have tried by calling "stopMocking", which is no use.

So how does OCPartialMockObject release, and why it can not find private setter method?

OCMockito version: 5.1.2 OCMock version: '3.4.3'.

erikdoe commented 4 years ago

Please ask questions regarding the use of OCMock on StackOverflow using the ocmock tag.