데이터 소스 개체에 대한 단위 테스트를 작성하고 있으며 그 개체의 일반 대리자 개체가 있습니다. 이 개체가 수행하는 작업은 특정 웹 서비스에서 일부 데이터를 가져온 다음 대리인에게 다시 전화하여 성공을 알리는 것입니다. 여기에 코드입니다 : OCMock : 스텁이 서명과 일치하지 않음
NSString *validProductId = @"34142977";
NSString *validSiteCode = @"someSiteCode";
[[dataSourceDelegateMock expect] dataSource:dataSource didFetchProductData:[OCMArg any] forProductWithId:validProductId];
[dataSource fetchProductWithId:validProductId andSiteCode:validSiteCode];
NSDate *runUntilDate = [NSDate dateWithTimeIntervalSinceNow:networkTimeOut];
while ([runUntilDate timeIntervalSinceNow] > 0) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:runUntilDate];
}
[dataSourceDelegateMock verify];
지금이 잘 작동하고 모든, 그리고 예상대로 한 네트워크를 10 초 이내에 일부 데이터로 응답으로, 테스트가 성공한다.
나는 네트워킹 코드를 테스트하는 방법이 아니라는 것을 알고 있습니다. 어떤 사람들은 그것을 다르게 할 것이고, 어떤 사람들은 이것을 통합 테스트라고 부르 겠지만, 그것은 내가이 시점에서 관심이있는 것이 아닙니다.
위의 코드는 정상적으로 작동하지만 네트워크가 일반적으로 그보다 훨씬 빠르다는 사실에 관계없이 매 10 초마다 실행됩니다.
지금은 네트워크에서 아직 응답하지 않은 경우 "아직 시간 초과되지 않은 경우"라는 의미의 while 루프에 다른 조건을 추가하려고합니다. 이런 방식으로, 나는 대부분의 시간 동안 훨씬 더 빠르게 테스트를 수행 할 수있었습니다.
이NSString *validProductId = @"34142977";
NSString *validSiteCode = @"someSiteCode";
__block BOOL dataSourceFetchedData = NO;
[[dataSourceDelegateMock expect] dataSource:dataSource didFetchProductData:[OCMArg any] forProductWithId:validProductId];
[[[dataSourceDelegateMock stub] andDo:^(NSInvocation * invocation) {
dataSourceFetchedData = YES;
}] dataSource:dataSource didFetchProductData:[OCMArg any] forProductWithId:[OCMArg any]];
[dataSource fetchProductWithId:validProductId andSiteCode:validSiteCode];
NSDate *runUntilDate = [NSDate dateWithTimeIntervalSinceNow:networkTimeOut];
while ([runUntilDate timeIntervalSinceNow] > 0 && dataSourceFetchedData == NO) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:runUntilDate];
}
[dataSourceDelegateMock verify];
분명히 여기에 아이디어는 즉시 대리인 콜백이 모의 위임 객체로 전송로 (didFetchProductData이 ...)이 부울 변수가 설정 될 것입니다 다음과 같이
그래서 나는 테스트를 수정 YES로 설정하면 while 루프가 종료되어 테스트 자체의 지속 시간이 단축됩니다.
마지막으로 문제는 : 내가 무엇을 하든지간에, 런타임시 대리인 콜백에 대해 호출되는 서명과 일치 할 수 없으므로 블록 안에 넣은 내용은 절대로 실행되지 않습니다. 테스트는 계속 진행되지만 더 빠르지는 않습니다.
많은 디버깅 후 validProductId 변수에서 문제를 찾아 냈습니다. 어떤 이유로 나는 이해할 수 없다. 반환 된 값은 메소드를 스터 빙할 때 설정 한 기대와 결코 일치하지 않을 것이다. 내가 어떻게 알아 ? 기대를 nil로 설정하고 데이터 소스가 nil을 반환하도록 강제하면 모든 것이 잘 작동하기 때문입니다.
내가 생각할 수있는 모든 것을 시도 했으므로 도움이 될 것입니다. 이 다시 호출 데이터 소스 방법 : 데이터 소스가 정확히이 전달되는 동일한 productId에 반환되는 참조 않도록
(void) fetchProductWithId:(NSString *)productId andSiteCode:(NSString *)siteCode {
NSString *urlString = [NSString stringWithFormat:itemApiString,siteCode,productId];
NSURL *url = [NSURL URLWithString:urlString relativeToURL:self.baseUrl];
[self.requestManager GET:url.absoluteString parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
[self.delegate dataSource:self didFetchProductData:responseObject forProductWithId:productId];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
[self.delegate dataSource:self didFailFetchProductDataForProductId:productId withError:error];
}];
}
난 정말 왜 지구상에서 이해할 수없는 예상 된 스텁 방식과 일치하지 않습니다.
대단히 감사합니다.
고맙습니다 만,이 방법은 해결책이지만 해결책이 아닙니다. – FTSwift