2015-09-27 2 views
3

Я пишу XCTest единичный тест в Swift. Идея состоит в том, что обратный вызов не должен вызываться в определенном случае.Что делать, если XCTestExpectation неожиданно

Так что я делаю, это

func testThatCallbackIsNotFired() { 

    let expectation = expectationWithDescription("A callback is fired") 
    // configure an async operation 

    asyncOperation.run() { (_) ->() in 
     expectation.fulfill() // if this happens, the test must fail 
    } 

    waitForExpectationsWithTimeout(1) { (error: NSError?) -> Void in 

     // here I expect error to be not nil, 
     // which would signalize that expectation is not fulfilled, 
     // which is what I expect, because callback mustn't be called 
     XCTAssert(error != nil, "A callback mustn't be fired") 
    } 
} 

Когда функция вызывается, все работает отлично: он терпит неудачу с сообщением «обратный вызов не должен быть уволен», который является именно то, что мне нужно.

Но если ожидания не оправдались, он терпит неудачу и говорит

Асинхронный ждать не удалось: Превышен таймаут 1 секунды, несбывшиеся ожидания: «Ответный обжигают».

Поскольку не выполненное ожидание - это то, что мне нужно, я не хочу иметь неудачный тест.

Есть ли у вас какие-либо предложения, что я могу сделать, чтобы этого избежать? Или, может быть, я могу достичь своей цели по-другому? Благодарю.

+0

Похоже, вам, возможно, потребуется пересмотреть код, который вы тестируете. Если код работает асинхронно, я, вероятно, хочу получить обратный вызов, когда это будет сделано, независимо от того, была ли ошибка. – nhgrif

+0

С учетом сказанного, если ваша цель состоит в том, чтобы вызывать только обратный вызов, когда есть ошибка, и ваш тест заботится только о том, равна или нет ошибка, и вы пишете код Swift, тогда почему ошибка является необязательной? Вы можете заверить, что это никогда не ноль в * компиляции * времени, просто делая его не факультативным. – nhgrif

+0

Спасибо за комментарий. Может быть, вы правы. Позвольте мне объяснить цель. Я работаю над кешем изображения. Логика такова: если изображение уже находится в памяти, оно немедленно возвращает его (обратный вызов не нужен). В противном случае вы получите изображение (или ошибку) из обратного вызова. Имеет ли это смысл? –

ответ

3

У меня была такая же проблема, и я раздражен тем, что вы не можете использовать обработчик для переопределения тайм-аута waitForExpectationsWithTimeout. Вот как я его решил (синтаксис Swift 2):

func testThatCallbackIsNotFired() { 
    expectationForPredicate(NSPredicate{(_, _) in 
     struct Holder {static let startTime = CACurrentMediaTime()} 

     if checkSomehowThatCallbackFired() { 
      XCTFail("Callback fired when it shouldn't have.") 
      return true 
     } 

     return Holder.startTime.distanceTo(CACurrentMediaTime()) > 1.0 // or however long you want to wait 
     }, evaluatedWithObject: self, handler: nil) 
    waitForExpectationsWithTimeout(2.0 /*longer than wait time above*/, handler: nil) 
} 
+0

Выглядит уродливо, но он работает. Благодарю. –

Смежные вопросы