Как проверить, что данные не записаны в NSPipe

Я работаю над каркасом регистрации в последнее время, и я позволяю пользователю предоставить NSPipe чтобы журналы отключались, если они не хотят, чтобы сообщения журнала передавались на консоль.

Logger может быть включен или отключен, и когда отключен, не должен отправлять какие-либо данные по трубе.

Легко проверить, были ли отправлены данные по каналу, когда включен регистратор, как availableData немедленно содержит данные, и блок NSFileHandleDataAvailableNotification/readabilityHandler запущен.

Однако, если вы должны были проверить, что данные не были переданы по конвейеру, и попытались применить ту же идею, что availableData не будет содержать никаких данных, тесты будут остановлены как availableData возвращается только после получения данных.

Я придумал одно решение, которое заключалось бы в том, чтобы прослушать уведомление и, если оно не было получено через X секунд, выполнить ожидание того, что уведомление не было получено, при условии, что ожидание будет выполнено дважды (в результате чего тест не пройден), если получено уведомление.

Проблема с этим подходом состоит в том, что если по какой-то причине канал действительно получает некоторые данные, как только ожидание выполняется в readabilityHandler блок, тест завершается сразу же, и ожидание не выполняется во второй раз:

func testDisabledLoggerDoesntLog() {
    let logger = Logger()
    let pipe = NSPipe()

    logger.pipe = pipe
    logger.enabled = false

    let expectation = expectationWithDescription("handler not triggered")
    logger.pipe!.fileHandleForReading.readabilityHandler = { handler in
        expectation.fulfill()
    }

    logger.debug("Test message")

    fulfillAfter(expectation, time: 2)

    waitForExpectationsWithTimeout(3, handler: nil)
}

func fulfillAfter(expectation: XCTestExpectation, time: Double = 4) {
    let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(time * Double(NSEC_PER_SEC)))
    dispatch_after(delayTime, dispatch_get_main_queue()) {
        expectation.fulfill()
    }
}

Какой лучший подход может привести к провалу теста, если канал получает данные, и к прохождению теста, если нет?

1 ответ

Решение

Как указано в комментариях, я нашел отдельное решение, которое записывает произвольные данные в канал, выполняет журнал (что может или не может привести к записи большего количества данных в канал), а затем извлекает данные из канала availableData,

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

let logger = Logger()
let pipe = NSPipe()

logger.pipe = pipe
logger.enabled = false
logger.useCurrentThread = true // The logs generally use a background thread to prevent interrupting the main queue. In this test, the current thread must be used in order for it to be synchronous.

let writtenData = "written data".dataUsingEncoding(NSUTF8StringEncoding)!
logger.pipe!.fileHandleForWriting.writeData(writtenData)

logger.debug("Test message")

XCTAssertEqual(logger.pipe!.fileHandleForReading.availableData.length, writtenData.length)
Другие вопросы по тегам