请使用 spring-cloud-contract 5.0.2 获取最新稳定版本!spring-doc.cadn.net.cn

Artifactory 中使用存根进行提供者契约测试,适用于非 Spring 应用程序

在此页面中,您将学习如何在非 Spring 应用程序中使用存根(stubs)并将其上传至 Artifactory,以进行提供者契约测试。spring-doc.cadn.net.cn

流程

您可以阅读 开发您的首个基于 Spring Cloud Contract 的应用,以了解使用 Nexus 或 Artifactory 中的存根进行提供者契约测试的流程。spring-doc.cadn.net.cn

设置消费者

对于消费者端,您可以使用一个 JUnit 规则。这样就无需启动 Spring 上下文了。以下列表展示了该规则(适用于 JUnit 4 和 JUnit 5);spring-doc.cadn.net.cn

JUnit 4 规则
@Rule
	public StubRunnerRule rule = new StubRunnerRule()
			.downloadStub("com.example","artifact-id", "0.0.1")
			.repoRoot("git://[email protected]:spring-cloud-samples/spring-cloud-contract-nodejs-contracts-git.git")
			.stubsMode(StubRunnerProperties.StubsMode.REMOTE);
JUnit 5 扩展
@RegisterExtension
	public StubRunnerExtension stubRunnerExtension = new StubRunnerExtension()
			.downloadStub("com.example","artifact-id", "0.0.1")
			.repoRoot("git://[email protected]:spring-cloud-samples/spring-cloud-contract-nodejs-contracts-git.git")
			.stubsMode(StubRunnerProperties.StubsMode.REMOTE);

设置生产者

默认情况下,Spring Cloud Contract 插件为生成的测试使用 Rest Assured 的 MockMvc 设置。由于非 Spring 应用不使用 MockMvc,您可以将 testMode 更改为 EXPLICIT,以向在特定端口上绑定的应用程序发送真实请求。spring-doc.cadn.net.cn

在本示例中,我们使用一个名为 Javalin 的框架来启动一个非 Spring HTTP 服务器。spring-doc.cadn.net.cn

假设我们有以下应用程序:spring-doc.cadn.net.cn

import io.javalin.Javalin;

public class DemoApplication {

	public static void main(String[] args) {
		new DemoApplication().run(7000);
	}

	public Javalin start(int port) {
		return Javalin.create().start(port);
	}

	public Javalin registerGet(Javalin app) {
		return app.get("/", ctx -> ctx.result("Hello World"));
	}

	public Javalin run(int port) {
		return registerGet(start(port));
	}

}

鉴于该应用程序,我们可以设置插件以使用 EXPLICIT 模式(即向真实端口发送请求),如下所示:spring-doc.cadn.net.cn

Maven
<plugin>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-contract-maven-plugin</artifactId>
	<version>${spring-cloud-contract.version}</version>
	<extensions>true</extensions>
	<configuration>
		<baseClassForTests>com.example.demo.BaseClass</baseClassForTests>
		<!-- This will setup the EXPLICIT mode for the tests -->
		<testMode>EXPLICIT</testMode>
	</configuration>
</plugin>
Gradle
contracts {
	// This will setup the EXPLICIT mode for the tests
	testMode = "EXPLICIT"
	baseClassForTests = "com.example.demo.BaseClass"
}

基类可能类似于以下内容:spring-doc.cadn.net.cn

import io.javalin.Javalin;
import io.restassured.RestAssured;
import org.junit.After;
import org.junit.Before;
import org.springframework.cloud.test.TestSocketUtils;

public class BaseClass {

	Javalin app;

	@Before
	public void setup() {
		// pick a random port
		int port = TestSocketUtils.findAvailableTcpPort();
		// start the application at a random port
		this.app = start(port);
		// tell Rest Assured where the started application is
		RestAssured.baseURI = "http://localhost:" + port;
	}

	@After
	public void close() {
		// stop the server after each test
		this.app.stop();
	}

	private Javalin start(int port) {
		// reuse the production logic to start a server
		return new DemoApplication().run(port);
	}
}

采用这种配置:spring-doc.cadn.net.cn