Why is my object's weak delegate property nil in my unit tests?

前端 未结 4 1051
既然无缘
既然无缘 2020-12-31 07:54

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         


        
相关标签:
4条回答
  • 2020-12-31 08:15

    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
    
    0 讨论(0)
  • 2020-12-31 08:20

    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.

    0 讨论(0)
  • 2020-12-31 08:22

    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...

    0 讨论(0)
  • 2020-12-31 08:24

    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...

    0 讨论(0)
提交回复
热议问题