是否可以直接在grails中使用Spring MVC Test,以及如何使用?

时间:2015-10-22 06:13:54

标签: grails grails-3.0 spring-mvc-test spring-restdocs

我们认为Spring Rest Doc非常适合记录rest api。但它基于Spring MVC Test,我们无法弄清楚如何在我的grails应用程序中使用Spring MVC Test(Grails 3.0.5)。

我尝试使用配置类(使用@Configuration@ComponentScan)将grails组件扫描到测试上下文中,但似乎没有加载任何内容(在向{执行http请求时) {1}},它得到了404)。

我还尝试直接配置grails控制器,并出现运行时错误。

  

无法自动装配字段:private reactor.bus.EventBus

我还尝试在测试类中添加mockmvc(来自grails),但收到了同样的错误。

请帮忙。

以下是一些代码示例。 我尝试的是将配置类或类位置或grails控制器添加到下面的测试类的ContextConfiguration。测试类本身基本上遵循@Integration引用。

spring rest doc

配置类(没用):

import org.junit.Before;
import org.junit.Rule;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.restdocs.RestDocumentation;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration
//TODO how to scan Grails components into the test context
public class QuestionRestSpec {
@Rule
public final RestDocumentation restDocumentation = new RestDocumentation("build/generated-snippets");
@Autowired
private WebApplicationContext context;

private MockMvc mockMvc;

@Before
public void setUp() {
    this.mockMvc = MockMvcBuilders.webAppContextSetup(context)
            .apply(documentationConfiguration(this.restDocumentation))
            .build();
}
}

1 个答案:

答案 0 :(得分:1)

不幸的是,似乎没有可能将MockMvc与Grails一起使用。致电MockMvc.perform失败:

HandlerMapping requires a Grails web request. Stacktrace follows:
java.lang.IllegalArgumentException: HandlerMapping requires a Grails web request
    at org.springframework.util.Assert.notNull(Assert.java:112) ~[spring-core-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.grails.web.mapping.mvc.UrlMappingsHandlerMapping.getHandlerInternal(UrlMappingsHandlerMapping.groovy:113) ~[grails-web-url-mappings-3.0.9.jar:3.0.9]
    at org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:299) ~[spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1120) [spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.test.web.servlet.TestDispatcherServlet.getHandler(TestDispatcherServlet.java:90) [spring-test-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:932) [spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) [spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967) [spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:858) [spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) [tomcat-embed-core-8.0.26.jar:8.0.26]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843) [spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:65) [spring-test-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) [tomcat-embed-core-8.0.26.jar:8.0.26]
    at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:167) [spring-test-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134) [spring-test-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:144) [spring-test-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    …

Spring REST Docs 1.1 will hopefully add support for REST Assured。这消除了对MockMvc的需求,而是允许通过在功能测试中对正在运行的服务器进行HTTP调用来记录API。

供参考,这是我使用的Spock规范:

package com.example.notes

import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import grails.test.mixin.integration.Integration
import grails.transaction.*
import org.junit.Rule;
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.restdocs.RestDocumentation;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext

import spock.lang.*

@Integration
@Rollback
class ApiDocumentationSpec extends Specification {

    @Rule
    public final RestDocumentation restDocumentation = new RestDocumentation("build/generated-snippets");

    @Autowired
    WebApplicationContext context

    MockMvc mockMvc

    def setup() {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
                .apply(documentationConfiguration(this.restDocumentation)).build();
    }

    def cleanup() {

    }

    void "list notes"() {
        when:
            MvcResult result = this.mockMvc.perform(get("/notes")).andReturn()
        then:
            result.andExpect(status().isOk())
                .andDo(document("notes-list-example"));
    }
}