【问题标题】:Mocking instance creation in Groovy with Powermock使用 Powermock 在 Groovy 中模拟实例创建
【发布时间】:2017-07-11 17:49:33
【问题描述】:

我正在尝试通过带有 Powermock (1.7.0RC2)、Mockito2 (2.4.0) 和 TestNG (6.8.21) 的 Groovy 类中的 new 运算符来模拟实例创建。但通常的方法是行不通的。这是我的课程和测试。

public class A {
    public String send() {
        B b = new B();
        return b.send();
    }
}    

public class B {       
    public String send() {
        return "SendFromOriginB";
    }
}

@PrepareForTest([A.class])
class TestConstructor extends PowerMockTestCase {
    @Mock
    private B bMock

    @Test
    void test() {
      A a = new A()

     given(bMock.send()).willReturn("Send from B mock")
     PowerMockito.whenNew(B.class).withNoArguments().thenReturn(bMock)
     assertEquals(a.send(), "Send from B mock")
    }
}

问题在于 A 类是一个 Groovy 类。而且似乎 Powermock.whenNew 不知道 new B() 正在调用。

因此,var b 包含 B 类的 普通实例 而不是 mock 并且测试失败。但是,如果 A 类是 Java 类,那么测试会按我的预期工作,并且 var b 包含我的 mock。 Groovy 通过自己的方式创建实例,我无法正确模拟它们。

有人知道如何在 Groovy 类中模拟实例创建吗?

【问题讨论】:

  • 您能否提供完整的可运行脚本,包括@Gape()imports
  • @alex-voronkov 你有没有想过如何模拟 Groovy 类的实例创建?我有同样的问题

标签: unit-testing groovy mockito testng powermock


【解决方案1】:

你明白 Groovy 不是 Java 吗?是什么让您认为适用于 Java 语言的构造适用于其他语言?

从这个意义上说:您的第一步应该是使用javap检查 Groovy 为 A 类创建的 class 文件。看看里面有什么。

除此之外:用 factory 替换 new 并允许 inject 该 factory 将允许您轻松测试,那时您甚至不需要 PowerMock。

【讨论】:

    【解决方案2】:

    我有两个建议!

    使用@CompileStatic:

    @CompileStatic // <- you can use on class level
    public class A {
    
        // Or you can use on method level 
        // depending on groovy version
        @CompileStatic
        public String send() {
            // 
        }
    }
    

    此注释将删除破坏 PowerMock.whenNew() 方法的元编程协议。

    我的第二个建议是使用Spock Framework!这个框架是基于 BDD 的,当你使用 groovy 时,它使你的测试代码非常干净和可读! Spock 也可以mock constructor

    您在 spock 中的测试代码可能是这样的:

    def "Given an class A, when B constructor returns a mock, a must use the mock"() {
        given:
        String sendFromBMock = "Send from B mock"
        and:
        bMock.send() >> sendFromBMock
        when:
        new B() >> bMock
        then:
        a.send() == sendFromBMock
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多