2

我有一些生成器类,用于 Jenkins Pipeline 中的自定义步骤。我想测试这些步骤(它们是 groovy 脚本),以及内部使用的模拟类。虽然测试脚本不是问题,但内部使用的模拟类是有问题的。

我尝试使用 Mockito 来模拟脚本成员,但我尝试的任何方法都没有成功。我找到了在脚本方法中模拟函数或属性的解决方案,但不是类对象。

所以这是(简化的)脚本。它使用充当 XML 生成器的类。

// XmlGenerator is custom class that makes some magic
// script is named myCustomStep.groovy
def call(def val) {
    def myXmlGenerator = new XmlGenerator()
    xmlGenerator.setValue(val)
    def xmlString = xmlGenerator.generate()
    writeFile file: "/some/file/path.xml", text: xmlString
}

我对模拟“writeFile”或“sh”没有任何问题,但我想模拟 XmlGenerator.generate() 方法,比如

@Test
void someTest() {
    def myCustomStep = loadscript("vars/myCustomStep.groovy")
    def generatorMockedMethod = mock(Function)
    myCustomStep.metaclass.myXmlGenerator.generate = generatorMockedMethod.&apply // Just my imagination of how I would like it to be
    helper.registerAllowedMethod("writeFile", [Map.class], { params ->
        println "File was saved: file: ${params.file}, text: ${params.text}"
    })

    myCustomStep val: "50"
    assert generatorMockedMethod.called(1)
4

1 回答 1

1

我设法通过 Groovy 内置的模拟机制做到了这一点

要测试的脚本:

    // XmlGenerator is custom class that makes some magic
    // script is named myCustomStep.groovy
    def call(def val) {
        def myXmlGenerator = new XmlGenerator()
        xmlGenerator.setValue(val)
        def xmlString = xmlGenerator.generate()
        writeFile file: "/some/file/path.xml", text: xmlString
    }

和测试本身

    @Test
    void someTest() {
        def myCustomStep = loadscript("vars/myCustomStep.groovy")

        def  xmlGenMock = StubFor(XmlGenerator)
        xmlGenMock.demand.with {
            setValue { }
            generate { "<?xml><\xml> "} // Name of method to mock, and value to be returned when called
        }

        helper.registerAllowedMethod("writeFile", [Map.class], { params ->
            println "File was saved: file: ${params.file}, text: ${params.text}"
        })

        xmlGenMock.use {
            myCustomStep val: "50"
        }

        xmlGenMock.verify()
    }

这里的技巧是“stub.use”方法。在该闭包中,存根类的所有实例都将替换为存根版本。如果您想模拟/存根更多的类,只需将一个闭包放在另一个闭包中,例如:

    def stubOne = StubFor(MyClassOne)
    def stubTwo = StubFor(MyClassTwo)

    stubOne.use {
        stubTwo.use {
            // Call to be tested 
        }    
    }
于 2019-08-23T12:55:16.810 回答