I am having below class
class TestClientSpec extends Specification {
TestClient testClient
RestTemplate restTemplate
def setup() {
restTemplate = Mock()
testClient = new TestClient(restTemplate)
}
def 'successful'() {
given:
def url = 'https://test123'
when:
testClient.getValue(url)
then:
1 * restTemplate.getForEntity(url, Test.class)
}
}
when I try to run this test got below error
Cannot create mock for class org.springframework.web.client.RestTemplate. Mocking of non-interface types requires a code generation library. Please put an up-to-date version of byte-buddy or cglib-nodep on the class path.
org.spockframework.mock.CannotCreateMockException: Cannot create mock for class org.springframework.web.client.RestTemplate. Mocking of non-interface types requires a code generation library. Please put an up-to-date version of byte-buddy or cglib-nodep on the class path.
After that I have added cglib dependnecy and it's working fine
implementation group: 'cglib', name: 'cglib-nodep', version: '3.3.0'
But not sure why it's throws the above error and how cglib fixing this?
Spock uses a bytecode generator lib, either cglib
or byte-buddy
, to generate classes at runtime in order to be able to mock classes.
The dependencies on these libs are optional, so that you can choose whether to use them or not, as you might as well use some dedicated mock libraries for all your mocking needs (e.g. PowerMock).
How adding a bytecode lib to the classpath can fix this?
Well, by enabling the necessary code in Spock... in case of Cglib, CglibMockFactory.
Spock seems to find out which lib is available to use for mocking at MockInstantiator... if you know Java reflection, doing that kind of thing is not hard, just do something like Class.forName("org.objenesis.Objenesis")
and if that doesn't throw ClassNotFoundException
you can use that.