Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

spock - mock static method is not working

I am trying to mock the one of static method readAttributes using groovy's metaClass convention, but the real method get invoked.

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

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();
}
like image 679
Suganthan Madhavan Pillai Avatar asked Apr 26 '16 13:04

Suganthan Madhavan Pillai


3 Answers

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

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.

like image 72
Suganthan Madhavan Pillai Avatar answered Oct 31 '22 14:10

Suganthan Madhavan Pillai


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

It would be possible if either:

  • code under test was written in groovy
  • mocked (altered) class must be instantiated in groovy code.

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

like image 24
Opal Avatar answered Oct 31 '22 13:10

Opal


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

In your case, it would be:

def filesClass = GroovySpy(Files, global: true)
filesClass.readAttributes(*_) >> null
like image 24
Fede Ogrizovic Avatar answered Oct 31 '22 12:10

Fede Ogrizovic