iOS8 плохое исключение доступа при выполнении юнит-тестов с ожиданием
У меня есть серия модульных тестов, написанных с использованием фреймворка XCTest. Первоначально они были созданы на iOS7, а затем выполнены в xCode6 на устройстве iOS8. Тесты выполняются последовательно, но затем я получаю EXC_BAD_ACCESS (код = 1, адрес 0xc) для следующего блока кода. Это происходит, когда тесты выполняются с помощью команды "Test" из xcode.
Если я выполню этот тест индивидуально с левой панели теста, он пройдет или не пройдёт нормально.
Вот что, я думаю, я делаю:
- Настройте ожидание
- Получить источник данных (старый возвращается немедленно)
- Асинхронное обновление источника данных из сетевого ресурса.
- Тестовый пример получает уведомление о обратном вызове делегата и выполняет ожидание
Как я могу убедиться, что могу выполнить все свои модульные тесты без исключения?
//модульный тест
-(void)testNetworkDataSourceUpdate
{
self.expectation = [self expectationWithDescription:@"Getting network datasource"];
DataSource* dataSource = [DataSourceProvider datasourceWithRefreshDelegate:self];
XCTAssertNotNil(dataSource, @"Should have datasource immediately available");
//Bad access here
[self waitForExpectationsWithTimeout:10.0 handler:^(NSError *error) {
}];
}
//Перезвоните
-(void)refreshDatasource:(NSMutableArray*)datasource
{
[self.expectation fulfill];
}
1 ответ
У меня была та же проблема, которая приводила к сбою при каждом вызове блока.
Ошибка была вызвана основным приложением, которое работало в фоновом режиме. Вы можете запретить это, добавив свой собственный AppDelegate для своей цели тестирования, который не запускает обычный поток приложений. Поэтому удалите старый AppDelegate из контрольной цели, создайте новую и добавьте ее в контрольную цель.
Затем вы должны изменить свой файл main.m, чтобы настроить правильный делегат приложения при запуске приложения:
int main(int argc, char *argv[]) {
@autoreleasepool {
int returnValue;
BOOL inTests = NSClassFromString(@"XCTest") != nil;
if (inTests) {
//use a special empty delegate when we are inside the tests
returnValue = UIApplicationMain(argc, argv, nil, @"AppDelegateTest");
} else {
//use the normal delegate
returnValue = UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
return returnValue;
} }