2014-10-21 2 views
0

저는 Parse Data 백엔드에 대한 액세스를 조롱하고 OCMock에 문제가 있습니다.왜 OCMock 및 Doo 기대는 처음에만 호출됩니까?

백엔드에 액세스하기위한 기본 데이터 액세스 메커니즘은 [PFQuery queryWithClassName:@"ClassName"]으로 구성된 PFQuery의 Parse를 통해 이루어집니다. 이것은 자연스럽게 테스트 솔기로 좋은 선택입니다.

나는이 게시물에 들어 가지 않을 이유 때문에 Partial mock을 사용하고 싶습니다. 대신 실제 PFQuery를 반환

, 나는 장비이 클래스의 방법과 같이 모의 객체를 반환 할 수 있습니다

id queryMock = OCMClassMock([PFQuery class]); 
OCMStub([queryMock queryWithClassName:className]).andDo(^(NSInvocation *invocation){ 
    id mockQuery = OC...; 
    NSLog(@">> CREATED MOCK QUERY: %@, %p", mockQuery, &mockQuery); 
    [invocation setReturnValue:&mockQuery]; 
}); 

을 ... 모의 쿼리가 너무처럼 설정되어 함께 :

PFQuery *query = [[PFQuery alloc] initWithClassName:className]; 

id mockQuery = OCMPartialMock(query); 

OCMStub([mockQuery findObjectsInBackgroundWithBlock:[OCMArg any]]).andDo(^(NSInvocation *invocation) { 
    typedef void (^FindObjectsBlock)(NSArray *, NSError *error); 

    FindObjectsBlock callback; 
    [invocation getArgument:&callback atIndex:2]; 

    NSArray *results = evaluateQueryResultArrayFromDataArray(query, objects); 

    callback(results, nil); 
}); 

그러나 SDK의 동작을 모방하기 위해이 메서드를 여러 번 호출 할 수 있기를 원하며 고유 한 모의 개체가 생성 될 것으로 예상합니다. 이건 중요하다.

OCMock의 클래스 메서드 조롱 기능을 사용하기로 결정했습니다. 클래스 메서드를 두 번 호출하면 조롱 (mocking) 동작이 처음에만 적용된다는 것을 알게되었습니다. 두 번째로, 조롱은 효과가 없다.

 NSLog(@"BEFORE first"); 
     PFQuery *firstQuery = [PFQuery queryWithClassName:@"THINGS"]; 
     NSLog(@"AFTER first"); 

     // Configure first query... 

     NSLog(@"BEFORE second"); 
     PFQuery *secondQuery = [PFQuery queryWithClassName:@"THINGS"]; 
     NSLog(@"AFTER second"); 

     // Configure second query... 

     expect(secondQuery).toNot.equal(firstQuery);   // OK 

     [firstQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) { 
      NSLog(@"THIS IS EXECUTED CORRECTLY %@", objects); // OK; returns array as expected 
     }]; 

     // The following query FAILS because the real underlying method is called. 
     [secondQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) { 
      NSLog(@"THIS DOESN'T EXECUTE RIGHT %@", objects); // FAILS 
     }]; 

흔적은 .andDo() 동작이 한 번만 실행되는 것을 분명히 보여줍니다.

2014-10-21 16:23:53.186 xctest[18380:209978] BEFORE first 
2014-10-21 16:23:53.188 xctest[18380:209978] >> CREATED MOCK QUERY: OCPartialMockObject(PFQuery), 0x7fff5e74d980 
2014-10-21 16:23:53.188 xctest[18380:209978] AFTER first 
2014-10-21 16:23:53.188 xctest[18380:209978] BEFORE second 
2014-10-21 16:23:53.188 xctest[18380:209978] AFTER second 

왜 그렇습니까?

+0

반복에 어떤 일이 발생했는지 '[... times : 3]'과 같은 프리미티브? – fatuhoku

+0

아직 구현할 시간을 찾지 못했습니다. –

+0

(이 댓글을 무시하고 아래 답변 참조) –

답변

1

주어진 클래스에 대해 하나의 mock 객체 만 클래스 메소드를 스텁 할 수 있습니다. 문서에서는 두 개의 mock 객체가 같은 클래스의 클래스 메소드를 스텁하려고 할 때 효과가 정의되지 않았다고 말합니다. 현재 구현에서는 나중에 모의 객체가 이전 모의 객체에서 스텁을 넘겨받습니다. 즉, 특정 클래스에 대한 모의 객체를 만들 때 같은 클래스에 대한 다른 모의 객체에 의해 생성 된 모든 클래스 메소드 스텁이 제거됩니다.

귀하의 경우 PFQuery 모의 의사를 작성하여 queryWithClassName: 메소드를 스터핑하십시오. 그 스텁이 호출 될 때 PFQuery에 대한 새로운 (부분) 모의가 생성됩니다. 위에서 설명한 OCMock의 현재 구현에서는 새로운 모의 객체가 PFQuery에 클래스 메소드를 스텁 (stub) 할 수있는 유일한 모의 객체이지만 queryWithClassName: 메소드에 대한 스텁을 선언하지 않았습니다 ...