Я изо всех сил пытаюсь найти лучший метод тестирования взаимодействия с Core Data в фоновом потоке. У меня есть следующий метод класса:Тестирование фона, сохраняющего объект Core Data с Kiwi
+ (void)fetchSomeJSON
{
// Download some json then parse it in the block
[[AFHTTPClient sharedClient] fetchAllThingsWithCompletion:^(id results, NSError *error) {
if ([results count] > 0) {
NSManagedObjectContext *backgroundContext = //... create a new context for background insertion
dispatch_queue_t background = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
dispatch_async(background, ^{ // If I comment this out, my test runs just fine
//... insert and update some entities
for (NSString *str in results) {
NSManagedObject *object = //...
}
});
}
}];
}
Я в настоящее время тестирования этого метода со следующим кодом Киви:
describe(@"MyAction", ^{
__block void (^completionBlock)(NSArray *array, NSError *error);
beforeEach(^{
// Stub the http client
id mockClient = [AFHTTPClient mock];
[WRNAPIClient stub:@selector(sharedClient) andReturn:mockClient];
// capture the block argument
KWCaptureSpy *spy = [mockClient captureArgument:@selector(fetchAllThingsWithCompletion:) atIndex:0];
[MyClass fetchSomeJSON]; // Call the method so we can capture the block
completionBlock = spy.argument;
// run the completion block
completionBlock(@[@"blah"], nil);
})
// If I remove the dispatch_async block, this test passes fine.
// If I add it in again the test fails, probably because its not waiting
it(@"should return the right count", ^{
// entityCount is a block that performs a fetch request count
NSInteger count = entityCount(moc, @"Task");
[[theValue(count) should] equal:theValue(4)];
})
// This works fine, but obviously I don't want to wait a second
it(@"should return the right count after waiting for a second", ^{
sleep(1);
NSInteger count = entityCount(moc, @"Task");
[[theValue(count) should] equal:theValue(4)];
});
};
Если я удалить dispatch_async
линии, то я могу получить мой тест, чтобы быстро запустить , Единственный способ, которым я могу получить свой тестовый набор для запуска при использовании dispatch_async
, - sleep(1)
после вызова блока завершения. Использование sleep()
заставляет меня думать, что я не подхожу к нему правильно. Я пробовал использовать shouldEventually
, но это не похоже на повторное получение значения count
.
Я не проверял это, но это выглядит намного более лаконичным способом ожидания. – squarefrog