Config ServletRegistrationBean в главном классе @SpringBootApplication, тест с ответом mockmvc 404 - PullRequest
0 голосов
/ 04 июля 2018

версия для весенней загрузки - 2.0.0. RELEASE.

тестовый класс:

@RunWith(SpringRunner.class)
@SpringBootTest(classes={Application.class},webEnvironment=SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc(secure = false)
public class ProcControllerTest {

@Autowired
private MockMvc mockMvc;

@Test
public void testGetProc() throws Exception {
    String requestUrl = "/app/rest/query/proc";
    // Request json body
    JSONObject jsonBody = new JSONObject();
    jsonBody.put("id", "101");
    String contentBody = jsonBody.toJSONString();

    MvcResult mvcResult = mockMvc.perform(post(requestUrl)
            .contentType(MediaType.APPLICATION_JSON_UTF8)
            .content(contentBody)
    ).andReturn();

    MockHttpServletResponse response = mvcResult.getResponse();
    assertThat(response.getStatus()).isEqualTo(200);


}

}

Я также попробовал другой тестовый конфиг:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {Application.class},
    webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
//@AutoConfigureMockMvc(secure = false)
public class ProcessInstanceControllerMockMvcTest {

private MockMvc mockMvc;

@Autowired
private WebApplicationContext wac;

@Before
public void before() throws Exception {
    mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
}

Application.class ниже:

@SpringBootApplication
@Import({ApplicationConfiguration.class})
public class Application extends SpringBootServletInitializer {

public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
}

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder 
builder) {
    return builder.sources(Application.class);
}


@Bean
public ServletRegistrationBean apiDispatcher(){
    DispatcherServlet api = new DispatcherServlet();
    api.setContextClass(AnnotationConfigWebApplicationContext.class);
    api.setContextConfigLocation(ApiDispatcherServletConfiguration.class.getName());
    ServletRegistrationBean registrationBean = new ServletRegistrationBean();
    registrationBean.setServlet(api);
    registrationBean.addUrlMappings("/api/*");
    registrationBean.setLoadOnStartup(1);
    registrationBean.setAsyncSupported(true);
    registrationBean.setName("api");
    return registrationBean;
}


@Bean
public ServletRegistrationBean appDispatcher(){
    DispatcherServlet app = new DispatcherServlet();
    app.setContextClass(AnnotationConfigWebApplicationContext.class);
    app.setContextConfigLocation(AppDispatcherServletConfiguration.class.getName());
    ServletRegistrationBean registrationBean = new ServletRegistrationBean();
    registrationBean.setServlet(app);
    registrationBean.addUrlMappings("/app/*");
    registrationBean.setLoadOnStartup(1);
    registrationBean.setAsyncSupported(true);
    registrationBean.setName("app");
    return registrationBean;
}

}

Журнал тестового прогона приведен ниже:

10: 58: 26.015 [main] [INFO] Инициализация Spring FrameworkServlet '' o.a.c.c.C. [. [. [/]. Log: 180
10: 58: 26.015 [main] [INFO] FrameworkServlet '': инициализация началась o.s.t.w.s.TestDispatcherServlet.initServletBean: 494
10: 58: 26.699 [main] [INFO] Mapped ...... Многострочный
10: 58: 30.408 [main] [INFO] FrameworkServlet '': инициализация завершена за 4392 мс o.s.t.w.s.TestDispatcherServlet.initServletBean: 513
10: 58: 31.159 [main] [INFO] SpringTemplateLoader для FreeMarker: использование загрузчика ресурсов [org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@61f80d55: дата запуска [ср. 04 июля 10:57:51 CST) корень иерархии контекста] и путь к загрузчику шаблонов [classpath: / templates /] o.s.u.f.SpringTemplateLoader.:62 10: 58: 31.163 [main] [INFO] ClassTemplateLoader для макросов Spring добавлен в конфигурацию FreeMarker o.s.w.s.v.f.FreeMarkerConfigurer.postProcessTemplateLoaders: 131 10: 58: 33.065 [main] [INFO] Запуск ProtocolHandler ["http-nio-auto-1"] o.a.c.h.Http11NioProtocol.log: 180
10: 58: 33.082 [main] [INFO] Использование общего селектора для сервлета запись / чтение o.a.t.u.n.NioSelectorPool.log: 180
10: 58: 33.114 [main] [INFO] Инициализация Spring FrameworkServlet 'app' o.a.c.c.C. [. [. [/]. Log: 180
10: 58: 33.115 [main] [INFO] FrameworkServlet 'app': инициализация началась o.s.w.s.DispatcherServlet.initServletBean: 494
10: 58: 33.121 [main] [INFO] Обновление WebApplicationContext для пространства имен 'app-servlet': дата запуска [ср. 04 июля 10:58:33 CST 2018]; parent: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@61f80d55 o.s.w.c.s.AnnotationConfigWebApplicationContext.prepareRefresh: 589 10: 58: 33.123 [main] [INFO] Успешно решенный класс для [com.fg.app.servlet.AppDispatcherServletConfiguration] o.s.w.c.s.AnnotationConfigWebApplicationContext.loadBeanDefinitions: 233
10: 58: 34.034 [main] [INFO] JSR-330 'javax.inject.Inject' аннотация найдена и поддерживается для автоматического подключения o.s.b.f.a.AutowiredAnnotationBeanPostProcessor.:154
10: 58: 26.699 [main] [INFO] Mapped ...... Многострочный
10: 58: 35.186 [main] [INFO] FrameworkServlet 'app': инициализация завершена за 2071 мс o.s.w.s.DispatcherServlet.initServletBean: 513
10: 58: 35.199 [main] [INFO] Инициализация Spring FrameworkServlet 'api' o.a.c.c.C. [. [. [/]. Log: 180
10: 58: 35.200 [main] [INFO] FrameworkServlet 'api': инициализация началась o.s.w.s.DispatcherServlet.initServletBean: 494
10: 58: 35.201 [main] [INFO] Обновление WebApplicationContext для пространства имен 'api-servlet': дата запуска [ср. 04 июля 10:58:35 CST 2018]; parent: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@61f80d55 o.s.w.c.s.AnnotationConfigWebApplicationContext.prepareRefresh: 589 10: 58: 35.202 [main] [INFO] Успешно решенный класс для [com.fg.app.servlet.ApiDispatcherServletConfiguration] o.s.w.c.s.AnnotationConfigWebApplicationContext.loadBeanDefinitions: 233
10: 58: 35.661 [main] [INFO] JSR-330 'javax.inject.Inject' аннотация найдена и поддерживается для автоматической проводки o.s.b.f.a.AutowiredAnnotationBeanPostProcessor.:154
10: 58: 26.699 [main] [INFO] Mapped ...... Многострочный
10: 58: 36.303 [main] [INFO] FrameworkServlet 'api': инициализация завершена за 1103 мс o.s.w.s.DispatcherServlet.initServletBean: 513
10: 58: 36.305 [main] [INFO] Tomcat запущен на портах: 53711 (http) с контекстным путем '' o.s.b.w.e.t.TomcatWebServer.start: 205
10: 58: 36.309 [main] [INFO] Запустил ProcControllerTest за 46,914 секунд (JVM работает для 51,157) c.f.a.ProcControllerTest.logStarted: 59
10: 58: 37.160 [Thread-9] [INFO] Закрытие org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@61f80d55: дата запуска [ср. 04 июля 10:57:51 CST 2018]; корень иерархии контекста o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext.doClose: 989
10: 58: 37.180 [Thread-9] [INFO] Закрытие JPA EntityManagerFactory для единицы сохраняемости «default» o.s.o.j.LocalContainerEntityManagerFactoryBean.destroy: 572
10: 58: 37.196 [Thread-9] [INFO] {dataSource-1} закрыт c.a.d.p.DruidDataSource.close: 1823
10: 58: 37.360 [localhost-startStop-2] [INFO] Закрытие WebApplicationContext для пространства имен 'app-servlet': дата запуска [ср. 04 июля 10:58:33 CST 2018]; parent: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@61f80d55 o.s.w.c.s.AnnotationConfigWebApplicationContext.doClose: 989
10: 58: 37.364 [localhost-startStop-2] [INFO] Закрытие WebApplicationContext для пространства имен 'api-servlet': дата запуска [ср. 04 июля 10:58:35 CST 2018]; parent: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@61f80d55 o.s.w.c.s.AnnotationConfigWebApplicationContext.doClose: 989

Результат теста: org.junit.CararisonFailure: Ожидаемый: 200 Фактический: 404

Из приведенного выше журнала, я думаю, класс TestDispatcherServlet является причиной. когда я использую TestRestTemplate, он не инициализирует TestDispatcherServlet и работает весело.

1 Ответ

0 голосов
/ 26 ноября 2018

MockMvc использует DispatcherServlet, отличный от зарегистрированного приложением. URL-адреса, которые вы передаете ему, должны совпадать с URL-адресами, указанными в аннотациях @Controller.

...