如何模拟在脚本中使用的groovy类?

时间:2019-08-19 23:13:28

标签: unit-testing groovy junit groovyscriptengine

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

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

因此,这是(简体)脚本。它使用充当XML生成器的Class。

// 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)

1 个答案:

答案 0 :(得分:0)

我设法通过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 
        }    
    }