如何测试没有数据写入 NSPipe

Posted

技术标签:

【中文标题】如何测试没有数据写入 NSPipe【英文标题】:How to test that no data is written to an NSPipe 【发布时间】:2016-07-03 13:23:44 【问题描述】:

我最近一直在研究一个日志框架,如果用户不希望日志消息进入控制台,我允许用户提供一个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()
    

如果管道接收到数据会导致测试失败,如果没有则导致测试通过?

【问题讨论】:

在文件处理程序上调用readDataOfLength(1) 怎么样?你能指望这会引发异常吗? @AaronBrager 不幸的是 readDataOfLength 没有通过。与availableData 一样,它是同步的,并在返回之前等待接收至少指定长度的数据。 @AaronBrager 我可以尝试在测试中将特定长度的数据写入管道,记录一些数据,并检查可用数据的长度是否等于我自己写的? ^ 这似乎工作得很好,测试现在按预期通过和失败。我已将其发布为答案,并有兴趣查看是否存在更好的解决方案。 【参考方案1】:

正如 cmets 中所述,我找到了一个单独的解决方案,它将任意数据写入管道,执行日志(这可能会或可能不会导致更多数据写入管道),然后从管道的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)

【讨论】:

以上是关于如何测试没有数据写入 NSPipe的主要内容,如果未能解决你的问题,请参考以下文章

如何测试从数据库读取并写入文件的弹簧批处理步骤?

Sqlserver中如何快速写入千万级测试数据

如何将数据写入stdin以供等待stdin输入的单独线程使用?

单元测试读取数据库失败是啥原因

Weka 如何将类标签附加到测试数据集?

如何修复单元测试中的错误? |断言错误