首页 > 解决方案 > cglib 如何修复 spock 中的模拟问题

问题描述

我正在上课

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)
    }
}

当我尝试运行此测试时出现以下错误

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.

之后我添加了 cglib 依赖,它工作正常

implementation group: 'cglib', name: 'cglib-nodep', version: '3.3.0'

但不确定为什么会引发上述错误以及 cglib 如何解决此问题?

标签: javagroovymockingspock

解决方案


Spock 使用字节码生成器库(或cglibbyte-buddy)在运行时生成类,以便能够模拟类。

对这些库的依赖是可选的,因此您可以选择是否使用它们,因为您不妨使用一些专用的模拟库来满足所有模拟需求(例如 PowerMock)。

如何将字节码库添加到类路径可以解决这个问题?

好吧,通过在 Spock 中启用必要的代码......在 Cglib 的情况下,CglibMockFactory

Spock 似乎找到了可用于在MockInstantiator上模拟的库……如果您知道 Java 反射,那么做这种事情并不难,只要做类似的事情Class.forName("org.objenesis.Objenesis"),如果没有抛出ClassNotFoundException,您就可以使用它。


推荐阅读