我不得不创建一个OutputStream
类(受此启发),它向日志记录器而不是stdout
写入,所以我想到了以下内容:
case class OutputStreamLogger(level: Level) extends OutputStream {
val logger: Logger = org.slf4j.LoggerFactory.getLogger("OutputStreamLogger")
private var mem = ""
/**
* Writes byte to Logger, flushes automatically at EOL
*
* @param b Int Int representation of character to get written
*
* @return Unit
*/
def write(b: Int): Unit = {
// To prevent internal conversion from byte to int
val bytes = new Array[Byte](1)
// Get least significant byte from int argument
bytes(0) = (b & 0xff).toByte
// Turn byte array into String
mem += new String(bytes)
// Automatically flush at EOL
if(mem.endsWith("n")) {
// Grab everything but newline
mem = mem.substring(0, mem.length - 1)
// Log it
flush()
}
}
/**
* Sends output bytes to logger at specified level
*
* @return Unit
*/
override def flush(): Unit = {
level match {
// Passing the format then the String eliminates
// need to check if logging at that level is enabled
case Level.TRACE => logger.trace("{}", mem)
case Level.DEBUG => logger.debug("{}", mem)
case Level.INFO => logger.info("{}", mem)
case Level.WARN => logger.warn("{}", mem)
case Level.ERROR => logger.error("{}", mem)
}
// Clear out buffer
mem = ""
}
}
我该如何进行单元测试呢?我看了单元测试OutputStream
s的其他例子,但他们都使用PrintStream
,我想使用我的OutputStreamLogger
,似乎没有测试write
和flush
方法
输出流的主要可测试性问题可能是这样的声明:
val logger: Logger = org.slf4j.LoggerFactory.getLogger("OutputStreamLogger")
您已经将记录器固定到一个具体的实例,该实例的初始化不能自定义。现在,您可以在单元测试期间使用slf4j日志记录配置,写入临时文件并将其读取回来。也许还有一个自定义的追加器可以写入内存缓冲区。
另一种可能性是更改该声明,并允许在实例创建时使用日志记录器规范。然后,您可以使用它来注入模拟日志记录器。
测试只是向输出流中写入一些内容,并查看是否有换行符将输出刷新到日志记录器。
BTW -你的实现看起来非常低效,因为它为每个写入的字节创建一个新的字符串。并且,拥有一个局部变量和一个成员具有相同的名称也会引起混淆。