OCMock - How to expect the content of an nsarray
I want to test that the values i insert in a database are sent back to the delegate of my class.
I tried to mock the delegate and expect the array i used to populate the database. It fails because the 2 NSArray have the same content but are different objects.
I've tried implementing isequal and hash methods on my model whithout success.
开发者_JS百科Here is the error log :
'OCMockObject[NewsListViewController]: unexpected method invoked: service:<RSSService-0x4c25b90-324400011.636966: 0x4c25b90> didFinishParsingRSSWithItems:(
description102362,
description102362,
description102362,
description102362,
description102362
)
expected: service:<OCMAnyConstraint: 0x4c10f30> didFinishParsingRSSWithItems:(
description102362,
description102362,
description102362,
description102362,
description102362
)'
How can i do that ?
Here is my test :
- (void) testServiceShouldNotLoadArticlesFromRSSFeedIfArticlesInDatabase {
NSArray *fakeArticles = [TestUtils createArticles:5];
[[DatabaseManager sharedManager] saveArticles:fakeArticles];
RSSService *mockService = [OCMockObject partialMockForObject:service];
id mockDelegate = [OCMockObject mockForClass:NewsListViewController.class];
[[mockDelegate expect] service:[OCMArg any] didFinishParsingRSSWithItems:fakeArticles];
mockService.delegate = mockDelegate;
[mockService loadAllArticles];
[mockService verify];
[mockDelegate verify];
}
and here is the method i'm testing :
- (void) loadAllArticles {
NSArray *articles = [self articlesFromDatabase];
[self.delegate service:self didFinishParsingRSSWithItems:articles];
}
Thanks for your help, Vincent
Get OCHamcrest! It provides a bunch of matchers that work with OCMock and make for much cleaner tests. Here's what your expectation would look like:
[[mockDelegate expect] service:[OCMArg any] didFinishParsingRSSWithItems:contains(article1, article2, article3, article4, article5, nil)];
// or, if order is unpredictable
[[mockDelegate expect] service:[OCMArg any] didFinishParsingRSSWithItems:containsInAnyOrder(article1, article2, article3, article4, article5, nil)];
If you really don't want to use hamcrest for some reason, you can create a method in your test class that evaluates the articles array. But I think it's kind of ugly:
- (void) testServiceShouldNotLoadArticlesFromRSSFeedIfArticlesInDatabase {
NSArray *fakeArticles = [TestUtils createArticles:5];
[[DatabaseManager sharedManager] saveArticles:fakeArticles];
RSSService *mockService = [OCMockObject partialMockForObject:service];
id mockDelegate = [OCMockObject mockForClass:NewsListViewController.class];
[[[mockDelegate stub] andCall:@selector(service:verifyFiveArticles:) onObject:self] service:[OCMArg any] didFinishParsingRSSWithItems:[OCMArg any]];
mockService.delegate = mockDelegate;
[mockService loadAllArticles];
[mockService verify];
[mockDelegate verify];
}
-(void)service:(id)service verifyFiveArticles:(NSArray *)articles {
STAssertEquals(5, [articles count]);
}
Is it possible that the two arrays have the same content but different addresses? Maybe trying comparing with isEqualToArray
[[mockDelegate expect] service:[OCMArg any]
didFinishParsingRSSWithItems:[OCMArg checkWithSelector:@selector(isEqualToArray:)
onObject:expectedArray]]
精彩评论