2

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

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

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

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

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

请帮忙。

以下是一些代码示例。我尝试将配置类或类位置或 grails 控制器添加到下面测试类的 ContextConfiguration 中。并且测试类本身基本上遵循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();
}
}

配置类(没有用):

@Configuration
@EnableWebMvc
@ComponentScan
public class AskConfig {
}
4

1 回答 1

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 有望增加对 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"));
    }
}
于 2015-10-23T11:33:40.987 回答