如何测试没有数据写入 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的主要内容,如果未能解决你的问题,请参考以下文章