使用specs2 + scalalogging进行单元测试记录器消息 [英] Unit test logger messages using specs2 + scalalogging

查看:82
本文介绍了使用specs2 + scalalogging进行单元测试记录器消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里有一个小问题,实际上不知道如何对记录器消息实施单元测试.当然,这听起来有些怪异,但是对我来说,这确实是一个有趣的话题.但是,让我更具体些.

I have a little problem here and really have no idea how to implement unit testing for logger messages. Of course, it sounds a little weird, but for me it's really interesting topic. But let me be more specific.

我有一些scala类和测试规范:

I have some scala class and test specification:

class Testable extends Logging {
  def method() = {
    // some method calls
    logger.info("Message1")
  }
}

class TestableSpec extends Specification with ShouldMatchers with Mockito {
  "Testable instance" should {
    // some important tests 

    "print proper log message during method call" in {
      // And how to test that logger really prints proper message ("Message1")? 
    }
  }
}

我的第一个想法是拦截底层的记录器引擎消息,但是由于在Testable类中使用了混合函数,因此似乎很难实现,因此任何实现此类想法的想法都将非常有帮助.

My first thought was to intercept underlying logger engine messages but it seems a little hard thing to implement due to usage of mixins in Testable class, therefore any ideas to do such things would be very helpful.

更新: 我终于实施了测试,并决定与社区分享我的解决方案.我们不能直接模拟scalalogging.Logger类,因为它是最终的,但我们仍然可以模拟基础的slf4j Logger.要澄清一个想法:

UPDATE: I finally implemented a test and decided to share my solution with community. We cannot mock scalalogging.Logger class directly because it's final but we still can mock underlying slf4j Logger. To clarify an idea:

class Testable extends Logging {
    def foo() = {
        // ...
        logger.info("Foo has been called")
    }
}

// Another imports are omitted.
import com.typesafe.scalalogging.slf4j.Logger
import org.slf4j.{Logger => Underlying}

class TestableSpec extends Specification with Mockito with ShouldMatchers {
    def initTestable(mocked: Underlying): Testable = {
        new Testable() {
            override lazy val logger = Logger(mocked)
        }
    }

    "Testable instance" should {
        "invoke logger with a proper message" in {
            val mocked = mock[Underlying]
            mocked.isInfoEnabled returns true // Should be set to true for test
            initTestable(mocked).foo()

            there was one(mocked).info("Foo has been called")
        }
    }
}

感谢Eric的帮助.他的回答是解决方案的关键.

Thanks Eric for his help. His answer was a key to the solution.

推荐答案

一种可能性是使用Mockito检查方法调用:

One possibility is to use Mockito to check method calls:

class Testable extends Logging {
  def method() = {
    // some method calls
    logger.info("Message1")
  }
}

class TestableSpec extends Specification with ShouldMatchers with Mockito {
   "Testable instance" should {
     "print proper log message during method call" in {
       val mockLogger = mock[Logger]
       val testable = new Testable {
         // switch the logger with a mock instance
         override val logger = mockLogger
       }
       testable.method()
       there was one(mockLogger).info("Message1")
     }
  }
}

这是主要思想,但您可能必须根据您的确切特征和日志记录框架对其进行调整:

This is the main idea but you might have to adapt it depending on your exact traits and logging framework:

  • 记录器必须是可覆盖的
  • info方法不能为最终方法(Mockito的限制之一)

这篇关于使用specs2 + scalalogging进行单元测试记录器消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆