spock - 模拟静态方法不起作用

spock - mock static method is not working

我正在尝试使用 groovy 的 metaClass 约定来模拟静态方法 readAttributes 中的一个,但是真正的方法被调用了。

这就是我模拟静态函数的方式:

def "test"() {
    File file = fold.newFile('file.txt')
    Files.metaClass.static.readAttributes = { path, cls ->
        null
    }

    when:
        fileUtil.fileCreationTime(file)
    then:
        1 * fileUtil.LOG.debug('null attribute')
}

我是不是做错了什么?

我的java方法

public Object fileCreationTime(File file) {
    try {
        BasicFileAttributes attributes = Files.readAttributes(file.toPath(), BasicFileAttributes.class);
        if(attributes == null) {
            LOG.debug("null attribute");
        }  
        //doSomething
    } catch (IOException exception) {
        //doSomething
    }
    return new Object();
}

简而言之,这是不可能的,请查看 this 问题。

如果是:

  • 被测代码写在groovy
  • mocked(已更改)class 必须在 groovy 代码中实例化。

解决方法是提取将属性返回给另一个 class 的逻辑,这将被模拟而不是直接使用 Files

我使用一级间接解决了这个问题。我创建了 test class 的实例方法,它充当此静态调用的包装器。

public BasicFileAttributes readAttrs(File file) throws IOException {
    return Files.readAttributes(file.toPath(), BasicFileAttributes.class);
}

并且在测试中我模拟了实例方法。

FileUtil util = Spy(FileUtil);
util.readAttrs(file) >> { null }

解决了我的问题。

您可以为此使用 GroovySpy,如 spock documentation

中所述

在你的情况下,它将是:

def filesClass = GroovySpy(Files, global: true)
filesClass.readAttributes(*_) >> null