Mock final class in Spock

23,102

Solution 1

This specification:

@Grab('org.spockframework:spock-core:1.0-groovy-2.4')
@Grab('cglib:cglib-nodep:3.1')

import spock.lang.*

class Test extends Specification {
    def 'lol'() {
        given: 
        def s = Mock(String) {
            size() >> 10
        }

        expect:
        s.size() == 10        
    }
}

ends with the following exception:

JUnit 4 Runner, Tests: 1, Failures: 1, Time: 29 Test Failure:
lol(Test) org.spockframework.mock.CannotCreateMockException:
Cannot create mock for class java.lang.String because Java mocks cannot mock final classes.
If the code under test is written in Groovy, use Groovy mock.

The solution is to use GroovyMock:

@Grab('org.spockframework:spock-core:1.0-groovy-2.4')
@Grab('cglib:cglib-nodep:3.1')

import spock.lang.*

class Test extends Specification {
    def 'lol'() {
        given: 
        def s = GroovyMock(String) {
            size() >> 10
        }

        expect:
        s.size() == 10        
    }
}

Which works well.

Solution 2

There is a third-party library https://github.com/joke/spock-mockable that seems to do the job. Not sure why it's not so popular.

Share:
23,102
Julian A.
Author by

Julian A.

Updated on September 17, 2021

Comments

  • Julian A.
    Julian A. almost 3 years

    Can spock mock final classes? If so, how? Search results brought up this gist, which would seem to imply so, but I can't find any examples of doing so. I've also found forum posts that say mocking final classes isn't supported.

    • cjstehno
      cjstehno over 8 years
      Sometimes, with Groovy it's best to just give it a try.
    • Julian A.
      Julian A. over 8 years
      @cjstehno I tried, and got an exception. But I figured maybe there's a special way of doing it that I don't know about.
    • Maximiliano De Lorenzo
      Maximiliano De Lorenzo about 6 years
      The short answer is no, there is an open issue about that. github.com/spockframework/spock/issues/735
  • Julian A.
    Julian A. over 8 years
    Could the difference with String.length() be because it's defined on the Java String class, not the Groovy version? This answer seems to suggest so.
  • mike rodent
    mike rodent over 6 years
    @JulianA. This is my experience too: GroovyMock seems to be no help with most Java class final methods. I'd like some clarfication on this... !
  • ptk
    ptk over 4 years
    Is there any other option other than using GroovyMock? Does Spock provide any other workaround for this problem?