简体   繁体   English

Spring Boot 1.4.2 @WebMvcTest返回状态404

[英]Spring Boot 1.4.2 @WebMvcTest returns status 404

I am using Spring Boot 1.4.2 and Jersey (jax-rs) to create a REST controller. 我使用Spring Boot 1.4.2和Jersey(jax-rs)来创建REST控制器。 I have followed the documentation on how to test REST Controllers ( Testing the Spring MVC slice ). 我已经按照文档介绍了如何测试REST控制器( 测试Spring MVC切片 )。 But my test returns 404 and I can't seem to find out why. 但我的测试返回404,我似乎无法找出原因。 The controller here is simplified but the problem remains. 这里的控制器已经简化,但问题仍然存在。

My question is how to get the 200 status when running the test? 我的问题是如何在运行测试时获得200状态?

HealthController.java HealthController.java

@Controller
@Path("/health")
public class HealthController {
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Health health() {
        return Health.up().build();
    }
}

Running the server and doing a query gives me this 运行服务器并进行查询给了我这个

%> curl -i http://localhost:8080/health
HTTP/1.1 200 
X-Application-Context: application
Content-Type: application/json
Content-Length: 21
Date: Sun, 27 Nov 2016 15:22:30 GMT

{
  "status" : "UP"
}% 

HealthControllerTest.java HealthControllerTest.java

@RunWith(SpringRunner.class)
@WebMvcTest(HealthController.class)
public class HealthControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void health() throws Exception {
        mockMvc.perform(get("/health").accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk()); // 200 expected
    }
}

This is what I get when running test 这是我在运行测试时得到的

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.4.2.RELEASE)

2016-11-27 16:22:08.254  INFO 9029 --- [           main] no.avec.controller.HealthControllerTest  : Starting HealthControllerTest on ducati.local with PID 9029 (started by avec in /Users/avec/Projects/RESTdemo)
2016-11-27 16:22:08.257 DEBUG 9029 --- [           main] no.avec.controller.HealthControllerTest  : Running with Spring Boot v1.4.2.RELEASE, Spring v4.3.4.RELEASE
2016-11-27 16:22:08.257  INFO 9029 --- [           main] no.avec.controller.HealthControllerTest  : No active profile set, falling back to default profiles: default
2016-11-27 16:22:09.294  INFO 9029 --- [           main] no.avec.controller.HealthControllerTest  : Started HealthControllerTest in 1.421 seconds (JVM running for 2.132)

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /health
       Parameters = {}
          Headers = {Accept=[application/json]}

Handler:
             Type = org.springframework.web.servlet.resource.ResourceHttpRequestHandler

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 404
    Error message = null
          Headers = {}
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

java.lang.AssertionError: Status 
Expected :200
Actual   :404

Judging by the @Path and @GET annotations you are using JAX-RS rather than Spring MVC. @Path@GET注释判断,您使用的是JAX-RS而不是Spring MVC。 @WebMvcTest is specifically for testing the web slice implemented using Spring MVC. @WebMvcTest专门用于测试使用Spring MVC实现的Web切片。 It filters out components that aren't Spring MVC controllers so it won't work with a web API implemented using JAX-RS. 它过滤掉不是Spring MVC控制器的组件,因此它不适用于使用JAX-RS实现的Web API。

When I look at your Controller class, it's a bit confusing. 当我查看您的Controller类时,它有点令人困惑。 You're using @Controller and then @Path and @GET annotations which means you're using Jersey. 您正在使用@Controller ,然后是@Path@GET注释,这意味着您正在使用Jersey。 I'll recommend to use @Component instead. 我建议改用@Component Although, @Controller extends @Component but still.... 虽然@Controller扩展@Component但仍然....

Anyway, you should use org.springframework.boot.test.web.client.TestRestTemplate for testing your rest resources. 无论如何,您应该使用org.springframework.boot.test.web.client.TestRestTemplate来测试您的其余资源。 For example 例如

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootApplicationTests {


    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    public void contextLoads() {
        final ResponseEntity<Health> entity = this.restTemplate.getForEntity("/health", Health.class);
        assertThat(entity.getStatusCode()).isEqualTo(OK);
    }

}

This should work for you. 这应该适合你。

I'm adding pom.xml which shows which dependencies you need to add to your pom.xml 我正在添加pom.xml,它显示了你需要添加到pom.xml的依赖项

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>no.hassan.bones</groupId>
    <artifactId>spring-boot-backbone</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>spring-boot-exmaple-jersey-mvc</name>
    <description>Doing Spring Boot with jersey and spring web-mvc</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jersey</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>               
            </plugin>
        </plugins>
    </build>


</project>

As you can see that I'm using both spring mvc ie spring-boot-starter-web and jersey as well spring-boot-starter-jersey . 你可以看到我正在使用弹簧mvc即spring-boot-starter-web和jersey以及spring-boot-starter-jersey Please remember that you need to add a @Configuration class which register your Jerse rest endpoints. 请记住,您需要添加一个@Configuration类来注册您的Jerse休息端点。 Here is a sample class for you 这是一个适合您的示例课程

import javax.ws.rs.ApplicationPath;

import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.context.annotation.Configuration;

/**
 * @author Iftikhar Ul Hassan
 */

@Configuration
@ApplicationPath("/rest")
public class JerseyConfig extends ResourceConfig {

    public JerseyConfig() {
        packages("package.path.where.HealthController.resides");

    }
}

Now you can serve your jersey rest enpoints under /rest/** 现在你可以在/rest/**下为你的球衣休息点提供服务

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM