Search code examples
gradlegroovymockitofinalstubbing

Groovy: Mockito UnfinishedStubbingException using verify (and inline mocks)


I'm trying to verify the calling of a method on a FileChooser.

I'm coding in Groovy, and this appears to be the problem.

I'm using the "incubating" Mockito feature which enables you to mock even a final class.

Code is:

    FileChooser mockFC = mock(FileChooser.class)
    doReturn(mockFC).when(spyCH).getFileChooser()
    ...
    verify( mockFC, times( 1 )).showOpenDialog( any() )

This gives:

org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
...
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallStatic(CallSiteArray.java:55) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:197) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:217) at core.ConsoleHandlerFTs.shouldShowFileChooserDialogOnEnteringO(ConsoleHandlerFTs.groovy:91)

(NB line 91 is the verify line)

... and then goes on to talk about final method (showOpenDialog is not final), missing whenReturn (not applicable), etc.

The Mockito in my build.gradle in GRADLE_HOME is version 2.7.22.
FileChooser is javafx.stage.FileChooser.
Java version is 1.8.0_121.

I created an entirely new Gradle project... and did the same thing, with just Java files. Mocking worked OK, test passed!

By "adding back" the bits and pieces which make Groovy function in a Gradle project I seemed to get to the problem: after

apply plugin: 'groovy'

and (in dependencies)

compile 'org.codehaus.groovy:groovy:3.0.0-alpha-1'

the problem reoccurred. That is, even without having created any .groovy files. I then tried earlier versions of groovy, down to 2.3.11. Same result.

From searching I thought the "bytebuddy" package might be implicated but adding the following line to dependencies ensured that no earlier versions were present in GRADLE_HOME:

compile 'net.bytebuddy:byte-buddy:1.6.11'

Still getting UnfinishedStubbingException come up when I run the Groovy test file.


Solution

  • "Workaround" ... for anyone who's typically moving from Java to Groovy.

    To learn Groovy I'm actually following a book, Groovy in Action, 2nd Ed, co-authored among others by JON SKEET!

    I have now got to the part about testing, which is sort of designed into the language, as well as taking advantage of some of Groovy's amazing power.

    It appears that Groovy's Spock testing framework is the way to go... and mocking final classes turns out to be possible with GroovyMock. I was able to write a test to do the job:

    class XXX extends Specification {
    
        @Rule
        public TextFromStandardInputStream systemInMock = emptyStandardInputStream()
        def xxx(){
            given:
            FileChooser fc = GroovyMock( FileChooser )
            ConsoleHandler ch = Spy( ConsoleHandler ){
                getFileChooser() >> fc
            }
            ch.setMaxLoopCount 10
            systemInMock.provideLines( "o" )
    
            when:
            com.sun.javafx.application.PlatformImpl.startup( {} )
            ch.loop()
            Thread.sleep( 2000L ) // needs improvement with a Latch or something!
    
            then:
            1 * fc.showOpenDialog( _ )
        }
    }
    

    ... it'd still be nice if some Groovy übermind (Jon, are you there?) could find out why Mockito produces this UnfinishedStubbingException in Groovy.

    NB you don't seem to be able to use GroovyMock in isolation within a Mockito test... it appears to be part of the Spock framework.