【问题标题】:Using ScalaTest to test java that contain @Autowired and private fields使用 ScalaTest 测试包含 @Autowired 和私有字段的 java
【发布时间】:2015-07-26 09:14:05
【问题描述】:

我已经开始使用 ScalaTest 来测试我的 Java 代码并且我喜欢它(我已经阅读了“Testing in Scala”一书)。

最近我一直在尝试测试一些包含标记为private@Autowired 的字段的java Spring 代码。这些字段没有设置方法。

我意识到我可以使用 JUnit + Mockito 使用注释 @InjectMocks@Mock 轻松测试它们,但是,我想使用 ScalaTest 和模拟框架(例如 Mockito 或 ScalaMock)来测试它们。

我的问题:Scalatest + Mockito 可以用于模拟私有字段还是这些框架是否要求我的 java 类具有为我的 private + @Autowired 字段定义的 public setter 方法?

【问题讨论】:

    标签: java scala mockito private scalatest


    【解决方案1】:

    根据我的经验,向那些自动装配的 bean 添加设置器要好得多。否则,您注入所需行为的唯一方法是通过复杂的反射过程,这只会使事情复杂化。

    要明确说明 setter 不能在测试之外使用,您可以做几件事:

    • 将它们标记为包私有

      void setDao(final Dao dao) {
          this.dao = dao;
      }
      
    • 使用来自 Guava 的 @VisibleForTesting 注释它们

    或者,现在可能是重新审视自动装配方案的好时机;如果您有很多要自动连接的 bean,它会变得非常笨拙。

    【讨论】:

    • 您好 Makoto ...感谢您的快速回复。这两个项目符号建议都很有帮助,我会考虑使用它们。但是,我特别询问 Scala 的任何 Mocking 框架(例如 ScalaMock 或 Mockito with MockitoSugar)是否支持测试包含无法通过公共访问器方法访问的私有字段的 java 代码。再次感谢!
    【解决方案2】:

    你可以在import org.mockito.MockitoAnnotations.Mock中使用@Mock注解

    @Mock private var someDao:SomeDao =_

    这可行,但不建议使用。它也被弃用了

    【讨论】:

      【解决方案3】:

      您可以使用 InjectMocks 来做到这一点。这是一个使用 ScalaTest 和 Mockito 来测试包含 @Autowired 成员的类的工作示例:

      import org.mockito.{MockitoAnnotations, InjectMocks, Mock}
      import org.scalatest.{FunSpec, BeforeAndAfter}
      import org.scalatest.Matchers._
      import org.mockito.Mockito._
      import org.springframework.beans.factory.annotation.Autowired
      
      class InjectMocksSpec extends FunSpec with BeforeAndAfter {
      
        @Mock
        var paramMock: MockedClass = null
      
        @InjectMocks
        var testClass = new TestClass()
      
        describe("InjectMocks") {
          it("should inject mock for Autowired field") {
            MockitoAnnotations.initMocks(this)
      
            when(paramMock.get).thenReturn("bar")
      
            testClass.test should be("bar")
      
            verify(paramMock, times(1)).get
          }
        }
      
      }
      
      class MockedClass {
        def get: String = {
          "foo"
        }
      }
      
      class TestClass {
        @Autowired
        var param: MockedClass = null
      
        def test: String = {
          param.get
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-05-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-10
        • 1970-01-01
        • 2018-08-10
        • 2020-08-03
        • 2016-10-25
        相关资源
        最近更新 更多