5

我们有一个 ServletFilter,我们想用 Spock 进行单元测试并检查对 HttpServletRequest 的调用。

以下代码抛出 java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/servlet/http/Cookie

def "some meaningless test"(){
    given:
    HttpServletRequest  servletRequest = Mock(HttpServletRequest)

    when:
    1+1

    then:
    true
}

JavaEE 5 API(以及因此的 Servlet API)位于类路径中。Spock 版本是 0.6-groovy-1.8。

我们将如何正确地做到这一点?它可以与 Mockito 一起使用,但我们会失去 Spock 嘲笑的魅力。

编辑:我们知道 Grails 和 Spring 内置的 Servlet 模拟功能,我们只想知道是否有办法使用 Spock 模拟。否则,您将混合使用模拟设置技术...

4

2 回答 2

4

Grails 自动为每个集成测试配置一个MockHttpServletRequest, MockHttpServletResponse, 并且MockHttpSession您可以在测试中使用它。

在单元测试中,您需要导入并实例化一个新的MockHttpServletRequest

import org.springframework.mock.web.MockHttpServletRequest

def "some meaningless test"(){
    given:
    def servletRequest = new MockHttpServletRequest()

    when:
    1+1

    then:
    true
}
于 2012-05-25T10:36:40.540 回答
2

Spock uses JDK dynamic proxies for mocking interfaces, and CGLIB for mocking classes. Mockito uses CGLIB for both. This seems to make a difference in some situations where mocked interfaces (like javax.servlet.http.HttpServletRequest) reference classes (like javax.servlet.http.Cookie). Apparently, in Spock's case the Cookie class gets loaded, which results in a class loading error because the classes in the servlet API Jar have no method bodies (rather than empty method bodies).

Currently, Spock doesn't provide a way to force the usage of CGLIB for interfaces. This means you can either put the servlet implementation Jar, rather than the API Jar, on the test class path (which is probably the safer bet anyway), or use Mockito.

于 2012-05-26T06:15:55.087 回答