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;
    } }
Другие вопросы по тегам