title: How to mock a property of an object conforming to a protocol and mocked by OCMock?
body: <p>I'm following the examples in <a href="https://rads.stackoverflow.com/amzn/click/com/0321774183" rel="nofollow noreferrer" rel="nofollow noreferrer">Test driven iOS Development</a> and in one case there is a unit test that ensures that a delegate gets a 'dumbed down' version of an error method. So without going into too many details here are the relevant objects:</p>
  
  <ul>
  <li><strong>communicator:</strong> object responsible for making the network calls</li>
  <li><strong>manager:</strong> instructs the communicator to make calls and then pushes result to its delegate.</li>
  <li><strong>delegate:</strong> manager delegate that conforms to the <code>StackOverflowManagerDelegate</code> protocol. gets the results and processes it.</li>
  </ul>
  
  <p>so this is what the test is: </p>
  
  <pre><code>@implementation QuestionCreationTests
  
  {
      @private
      StackOverflowManager *mgr;
  }
  - (void)testErrorReturnedToDelegateIsNotErrorNotifiedByCommunicator {
      MockStackOverflowManagerDelegate *delegate =
      [[MockStackOverflowManagerDelegate alloc] init];
      mgr.delegate = delegate;
      NSError *underlyingError = [NSError errorWithDomain: @"Test domain"
                                                     code: 0 userInfo: nil];
      [mgr searchingForQuestionsFailedWithError: underlyingError];
      XCTAssertFalse(underlyingError == [delegate fetchError],
                    @"Error should be at the correct level of abstraction");
  }
  </code></pre>
  
  <p>this is the implementation of <code>searchingForQuestionsFailedWithError</code> in StackOverflowManager, where the manager simply dumbs down the original error returned by the communicator and sends the dumbed down version to the delegate. </p>
  
  <pre><code>- (void)searchingForQuestionsFailedWithError:(NSError *)error {
      NSDictionary *errorInfo = [NSDictionary dictionaryWithObject: error
                                                            forKey: NSUnderlyingErrorKey];
      NSError *reportableError = [NSError
                                  errorWithDomain: StackOverflowManagerSearchFailedError
                                  code: StackOverflowManagerErrorQuestionSearchCode
                                  userInfo:errorInfo];
      [delegate fetchingQuestionsOnTopic: nil
                         failedWithError: reportableError];
  }
  </code></pre>
  
  <p>the author suggests that for this to work.. we actually have to create a mock object for the manager delegate like so: </p>
  
  <pre><code>@interface MockStackOverflowManagerDelegate : NSObject &lt;StackOverflowManagerDelegate&gt;
  @property (strong) NSError *fetchError;
  
  @end
  
  @implementation MockStackOverflowManagerDelegate
  
  @synthesize fetchError;
  
  - (void)fetchingQuestionsOnTopic: (Topic *)topic
                   failedWithError: (NSError *)error {
      self.fetchError = error;
  }
  
  @end
  </code></pre>
  
  <p>this is the declaration of <code>StackOverflowManagerDelegate</code>:</p>
  
  <pre><code>@protocol StackOverflowManagerDelegate &lt;NSObject&gt;    
  - (void)fetchingQuestionsOnTopic: (Topic *)topic
                   failedWithError: (NSError *)error {    
  @end
  </code></pre>
  
  <hr>
  
  <p><strong>Question:</strong> I've been going over all the examples of the book and trying to use OCMock instead of the manually made ones like the author is doing.. (i just thought it would be a lot less time consuming). Everything has worked so far.. but i'm stuck here.. how do I fake a property called <code>fetchError</code> on delegate? This is what I have right now:</p>
  
  <pre><code>- (void)testErrorReturnedToDelegateIsNotErrorNotifiedByCommunicator {
      id &lt;StackOverflowManagerDelegate&gt; delegate = 
         [OCMockObject mockForProtocol:@protocol(StackOverflowManagerDelegate)];
      mgr.delegate = delegate;
  
      NSError *underlyingError = [NSError errorWithDomain: @"Test domain"
                                                     code: 0 userInfo: nil];
  
      [mgr searchingForQuestionsFailedWithError: underlyingError];
  
      // compiler error here: no known instance method for selector 'fetchError'
      XCTAssertFalse(underlyingError == [mgr.delegate fetchError], @"error ");
  }
  </code></pre>
  
  <p>In the guts of manager, manager calls <code>fetchingQuestionsOnTopic</code> on the delegate.. I know I can fake that method by <a href="http://ocmock.org/features/" rel="nofollow noreferrer">using</a> <code>[[[delegate stub] andCall:@selector(differentMethod:) onObject:differentObject] fetchingQuestionsOnTopic:[OCMArg any]]</code> where <code>differentMethod</code> would do whatever I want it to do.. I just don't know what to do with the result of <code>differentMethod</code>: I don't know how to store it in a mocked out property of delegate. </p>
  
  <hr>
  
  <p><strong>update:</strong> as a follow up to the answer below.. here is the implementation of unit test that ensures that the underlying error is still made available to the delegate:</p>
  
  <pre><code>- (void)testErrorReturnedToDelegateDocumentsUnderlyingError {
      MockStackOverflowManagerDelegate *delegate =
      [[MockStackOverflowManagerDelegate alloc] init];
      mgr.delegate = delegate;
      NSError *underlyingError = [NSError errorWithDomain: @"Test domain"
                                                     code: 0 userInfo: nil];
      [mgr searchingForQuestionsFailedWithError: underlyingError];
      XCTAssertEqual([[[delegate fetchError] userInfo]
                            objectForKey: NSUnderlyingErrorKey], underlyingError,
                           @"The underlying error should be available to client code");
  }
  </code></pre>
  
  <p>and here is the OCMock version of it:</p>
  
  <pre><code>- (void)testErrorReturnedToDelegateDocumentsUnderlyingErrorOCMock {
      id delegate =
      [OCMockObject mockForProtocol:@protocol(StackOverflowManagerDelegate)];
      mgr.delegate = delegate;
  
      NSError *underlyingError = [NSError errorWithDomain: @"Test domain"
                                                     code: 0 userInfo: nil];
  
      [[delegate expect] fetchingQuestionsFailedWithError:
         [OCMArg checkWithBlock:^BOOL(id param) {
  
          return ([[param userInfo] objectForKey:NSUnderlyingErrorKey] == underlyingError);
  
      }]];
  
      [mgr searchingForQuestionsFailedWithError: underlyingError];
  
      [delegate verify];
  }
  </code></pre>