Исключение плохого доступа iOS8 при выполнении модульных тестов с ожиданием

У меня есть серия модульных тестов, написанных с использованием XCTest framework. Первоначально они были созданы на iOS7, а затем выполнены в xCode6 на устройстве iOS8. Тесты выполняются последовательно, но затем я получаю EXC_BAD_ACCESS (код = 1, адрес 0xc) для следующего блока кода. Это происходит, когда тесты выполняются с помощью команды «Тест» из 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];
}

person Alex Stone    schedule 13.10.2014    source источник


Ответы (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;
    } }
person Patrick Haaser    schedule 19.10.2015