在应用程序中,控制器使用javax.ws.rs
注释进行注释。
据我从文档和示例项目了解,我必须定义一个BaseTestClass
,如下所示:
public class BaseTestClass {
public static WebTarget webTarget;
private static Server server;
private static Client client;
@BeforeClass
public static void setupTest() throws Exception {
int port = findAvailableTcpPort(10000);
URI baseUri = UriBuilder.fromUri("http://localhost").port(port).build();
// Create Server
server = new Server(port);
// Configure ServletContextHandler
ServletContextHandler context = new ServletContextHandler(
ServletContextHandler.SESSIONS);
context.setContextPath("/");
server.setHandler(context);
// Create Servlet Container
ServletHolder jerseyServlet = context
.addServlet(org.glassfish.jersey.servlet.ServletContainer.class, "/*");
jerseyServlet.setInitOrder(0);
// Tells the Jersey Servlet which REST service/class to load.
jerseyServlet.setInitParameter("jersey.config.server.provider.classnames",
MyController.class.getCanonicalName());
// Start the server
server.start();
ClientConfig clientConfig = new ClientConfig();
client = ClientBuilder.newClient(clientConfig);
webTarget = client.target(baseUri);
try {
server.start();
} catch (Exception ex) {
throw new IllegalStateException(ex);
}
}
@AfterClass
public static void cleanupTest() {
if (client != null) {
client.close();
}
if (server != null) {
try {
server.stop();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
目前尚不清楚如何以这种方式正确定义我的Spring配置。
我定义的存根:
package contracts
import org.springframework.cloud.contract.spec.Contract
Contract.make {
name("contract_update")
request {
method 'PUT'
url '/xxx/v1/api'
headers {
header 'Content-Type': 'application/vnd.org.springframework.cloud.contract.verifier.twitter-places-analyzer.v1+json'
}
body(file("update_request.json"))
}
response {
status OK()
headers {
header 'Content-Type': 'application/vnd.org.springframework.cloud.contract.verifier.twitter-places-analyzer.v1+json'
}
body(file("update_response.json"))
}
}
构建时,测试失败,预期200并收到404。我的猜测是,由于应用程序上下文加载失败,因此应用程序实际上未正确加载,因此未找到映射。
为了支持我的猜测,以下是启动服务器时发现的日志:
Nov 12, 2019 6:27:36 PM org.glassfish.jersey.server.spring.SpringComponentProvider initialize
SEVERE: Spring context lookup failed, skipping spring component provider initialization.
答案 0 :(得分:0)
请检查新添加的带有Spring示例(https://github.com/spring-cloud-samples/spring-cloud-contract-samples/tree/master/producer_jaxrs_spring)的Spring Cloud Contract JaxRS。为了方便起见,我在这里复制其内容
配置
@SpringBootApplication
public class ProducerWithJaxRsApplication {
public static void main(String[] args) {
SpringApplication.run(ProducerWithJaxRsApplication.class, args);
}
@Bean
PersonCheckingService personCheckingService() {
return argument -> argument.getAge() >= 20;
}
}
@Component
class JerseyConfig extends ResourceConfig {
JerseyConfig() {
register(FraudDetectionController.class);
}
}
控制器(PersonCheckingService
是一种方法的接口)。
package com.example.beerapiproducerjaxrs;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import com.example.beerapiproducerjaxrs.model.FraudCheck;
import com.example.beerapiproducerjaxrs.model.FraudCheckResult;
import org.springframework.web.bind.annotation.RestController;
import static com.example.beerapiproducerjaxrs.model.FraudCheckStatus.NOT_OK;
import static com.example.beerapiproducerjaxrs.model.FraudCheckStatus.OK;
@RestController
@Path("/")
public class FraudDetectionController {
private final PersonCheckingService service;
public FraudDetectionController(PersonCheckingService service) {
this.service = service;
}
@POST
@Path("/check")
@Produces("application/json;charset=utf-8")
@Consumes("application/json;charset=utf-8")
public FraudCheckResult fraudCheck(FraudCheck fraudCheck) {
if (oldEnough(fraudCheck)) {
return new FraudCheckResult(OK);
}
return new FraudCheckResult(NOT_OK);
}
private boolean oldEnough(FraudCheck fraudCheck) {
return service.shouldGetBeer(fraudCheck);
}
}
测试的基类
package com.example;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import com.example.beerapiproducerjaxrs.ProducerWithJaxRsApplication;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {ProducerWithJaxRsApplication.class},
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public abstract class BeerRestBase {
@LocalServerPort int port;
public WebTarget webTarget;
@Before
public void setup() {
this.webTarget = ClientBuilder.newClient().target("http://localhost:" + this.port + "/");
}
}
插件设置(Gradle)
contracts {
packageWithBaseClasses = 'com.example'
testMode = "JAXRSCLIENT"
}
还有插件设置(Maven)
<plugin>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-contract-maven-plugin</artifactId>
<version>${spring-cloud-contract.version}</version>
<extensions>true</extensions>
<configuration>
<packageWithBaseClasses>com.example</packageWithBaseClasses>
<testMode>JAXRSCLIENT</testMode>
</configuration>
</plugin>