如何为自定义OutputStream编写单元测试

时间:2016-10-05 17:57:50

标签: java scala unit-testing mockito outputstream

我必须创建一个OutputStream类(受this启发)写入记录器而不是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,但他们都使用了PrintStream我希望使用OutputStreamLogger并且似​​乎没有测试writeflush方法

1 个答案:

答案 0 :(得分:1)

输出流的主要可测试性问题可能是此声明:

val  logger:  Logger  =  org.slf4j.LoggerFactory.getLogger("OutputStreamLogger")

您已将记录器固定为具体实例,无法自定义该实例的初始化。您现在可以在单元测试期间使用slf4j日志记录配置写入临时文件并将其读回。也许还有一个可用的自定义appender写入内存缓冲区。

另一种可能性是更改该声明并在实例创建时允许记录器规范。然后,您可以使用它来注入模拟记录器。

然后测试只是在输出流中写入内容并查看换行符是否将输出刷新到记录器。

BTW - 您的实现效率非常低,因为它为每个写入的字节创建一个新字符串。拥有一个局部变量和一个同名的成员也令人困惑。