我使用Spring Boot 1.4.2和Jersey(jax-rs)来创建REST控制器。我已经按照文档介绍了如何测试REST控制器(Testing the Spring MVC slice)。但我的测试返回404,我似乎无法找出原因。这里的控制器已经过简化,但问题仍然存在。
我的问题是如何在运行测试时获得200状态?
HealthController.java
@Controller
@Path("/health")
public class HealthController {
@GET
@Produces(MediaType.APPLICATION_JSON)
public Health health() {
return Health.up().build();
}
}
运行服务器并进行查询会给我
%> 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
@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
}
}
这是我在运行测试时得到的
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: 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
答案 0 :(得分:2)
通过@Path
和@GET
注释判断您使用的是JAX-RS而不是Spring MVC。 @WebMvcTest
专门用于测试使用Spring MVC实现的Web切片。它过滤掉了不是Spring MVC控制器的组件,因此它不能使用JAX-RS实现的Web API。
答案 1 :(得分:0)
当我查看您的Controller类时,它有点令人困惑。您正在使用@Controller
,然后使用@Path
和@GET
注释,这意味着您正在使用Jersey。我建议改用@Component
。虽然@Controller
延伸@Component
但仍然......
无论如何,您应该使用org.springframework.boot.test.web.client.TestRestTemplate
来测试您的其余资源。例如
@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);
}
}
这应该适合你。
我添加了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>
你可以看到我同时使用弹簧mvc,spring-boot-starter-web
和球衣spring-boot-starter-jersey
。请记住,您需要添加一个@Configuration
类来注册您的Jerse休息端点。这是一个样本类
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");
}
}
现在,您可以在/rest/**