I have a pretty simple setup for this unit test. I have a class that has a delegate property:
@interface MyClass : NSObject
...
@property (nonatomic, weak) i
A workaround is to use Partial Mocks.
@interface TestMyDelegateProtocolDelegate : NSObject <MyDelegateProtocol>
@end
@implementation TestMyDelegateProtocolDelegate
- (void)someMethod {}
@end
@implementation SomeTest {
- (void)testMyMethod_WithDelegate {
id<MyDelegateProtocol> delegate = [[TestMyDelegateProtocolDelegate] alloc] init];
id delegateMock = [OCMockObject partialMockForObject:delegate]
[[[delegateMock expect] someMethod]
myClassIvar.connectionDelegate = delegate;
[myClass someOtherMethod];
STAssertNoThrow([delegate verify], @"should have called someMethod on delegate.");
}
@end
I am no ARC expert but my guess is that mockDelegateHelper()
is returning a weak object. As a result delegate
is nil before the second line of code executes. I would venture to guess that either the mockDelegateHelper()
is the culprit or that OCMock is getting in the way with how it manipulates and creates objects.
This is a bug in the iOS runtime. The following discussion has more detail. In a nutshell, the iOS ARC runtime can't seem to handle weak references to proxies. The OSX runtime can.
http://www.mulle-kybernetik.com/forum/viewtopic.php?f=4&t=252
As far as I understand from the discussion a bug report has been filed with Apple. If anyone has a sensible idea for a workaround...
I don't really know what's happening here, but OCMock returns an autoreleased NSProxy
-descendant from the mockForProtocol: method, which I think is right. Maybe ARC has problems with NSProxies? Anyway, I've overcome this problem by declaring the variable __weak
:
- (void)testMyMethod_WithDelegate {
// maybe you'll also need this modifier inside the helper
__weak id delegate = mockDelegateHelper();
...
It really doesn't need to be __strong
(the default) in this case, as it's autoreleased and you're not keeping it around...