spock - mock static method is not working
Solution 1
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.
Solution 2
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.
Solution 3
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
Suganthan Madhavan Pillai
You can reach me @ [email protected] I am active here: https://github.com/msuganthan
Updated on August 15, 2020Comments
-
Suganthan Madhavan Pillai over 3 years
I am trying to mock the one of static method
readAttributes
using groovy'smetaClass
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(); }
-
Opal about 8 years@Suganthan have you copied the example I provided as is? Cloaure's args are also very important.
-
Suganthan Madhavan Pillai about 8 yearsYes, I did the same, the intermediate assertion workd with no issue, but still the method get invoked
-
Opal about 8 years@Suganthan could you please then provide na runnable example? Without it, it might difficult to help.
-
Opal about 8 years@Suganthan, if you found my answer useful please accept and upvote it.
-
Suganthan Madhavan Pillai about 8 yearsI thought it is due to final class(Files) and it is private method is a root cause
-
Opal about 8 years@Suganthan, final classes can be mocked as well, see here
-
Suganthan Madhavan Pillai about 8 yearsSorry it is not private method
private constructor
.Private Constructor
might be a cause. Files having private constructor, but not theString class
-
Opal about 8 years@Suganthan, may be. However in groovy
private
is notprivate
at all ;) -
Suganthan Madhavan Pillai about 8 yearsYes, that make sense, sure I ll to find out the root cause and update my answer :)
-
imy over 3 yearsThis does not work when mocking static (Java) class within the object of test. In other words, the one instantiated not from Groovy. See stackoverflow.com/questions/15824315/…