跳到主要内容

针对非 Spring 应用在 Artifactory 中使用存根进行提供者契约测试

DeepSeek V3 中英对照 Provider Contract Testing with Stubs in Artifactory for a non-Spring Application

在本页面中,您将学习如何对非Spring应用程序以及上传到Artifactory的存根进行提供者契约测试。

流程​

你可以阅读开发首个基于Spring Cloud Contract的应用程序,了解在Nexus或Artifactory中使用存根进行提供者契约测试的流程。

设置消费者​

对于消费者端,你可以使用JUnit规则。这样,你就不需要启动Spring上下文。以下清单展示了这样的规则(在JUnit4和JUnit5中);

JUnit 4 规则

@Rule
public StubRunnerRule rule = new StubRunnerRule()
.downloadStub("com.example","artifact-id", "0.0.1")
.repoRoot("git://git@github.com: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://git@github.com:spring-cloud-samples/spring-cloud-contract-nodejs-contracts-git.git")
.stubsMode(StubRunnerProperties.StubsMode.REMOTE);

设置生产者​

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

在这个示例中,我们使用一个名为 Javalin 的框架来启动一个非 Spring 的 HTTP 服务器。

假设我们有以下应用程序:

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 模式(即向真实端口发送请求),具体配置如下:

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"
}

基类可能类似于以下内容:

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 Cloud Contract 插件配置为使用 EXPLICIT 模式,以发送真实请求而非模拟请求。

  • 我们定义了一个基类,该基类:

    • 为每个测试在随机端口上启动 HTTP 服务器。
    • 配置 Rest Assured 向该端口发送请求。
    • 在每个测试后关闭 HTTP 服务器。