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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36867072/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 01:57:15  来源:igfitidea点击:

spock - mock static method is not working

javaunit-testinggroovyspock

提问by Suganthan Madhavan Pillai

I am trying to mock the one of static method readAttributesusing groovy's metaClassconvention, but the real method get invoked.

我正在尝试readAttributes使用 groovy 的metaClass约定来模拟静态方法之一,但实际方法被调用。

This is how I mocked the static function:

这就是我嘲笑静态函数的方式:

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')
}

Am I doing something wrong here?

我在这里做错了吗?

My java method

我的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();
}

采纳答案by Suganthan Madhavan Pillai

I resolved the issue using one level of indirection. I created an instance method of the test classwhich acts like a wrapper for this static call.

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

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

and from the test I mocked the instance method.

从测试中我嘲笑了实例方法。

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

which resolved my issue.

这解决了我的问题。

回答by Opal

The short answer is that it's not possible, please have a look at thisquestion.

简短的回答是这是不可能的,请看一下这个问题。

It would be possible if either:

如果以下任一情况是可能的:

  • code under test was written in groovy
  • mocked(altered) class must be instantiated in groovy code.
  • 被测代码是用 groovy 编写的
  • 模拟(更改)类必须在常规代码中实例化。

The workaround is to extract the logic returning the attributes to another class which will be mocked instead of use Filesdirectly.

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

回答by Fede Ogrizovic

you can use GroovySpy for this, as stated in spock documentation

您可以为此使用 GroovySpy,如spock 文档中所述

In your case, it would be:

在您的情况下,它将是:

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