簡體   English   中英

使用 WireMock 的 Spring JUnit 測試中的多個應用程序上下文

[英]Multiple Application Contexts in Spring JUnit test with WireMock

我有以下情況:

@Transactional
@SpringBootTest
@ActiveProfiles("test")
@AutoConfigureMockMvc
@AutoConfigureWireMock(port = 0)
public abstract class IntegrationTest {
}

public class Test1 extends IntegrationTest {
  // Tests that use WireMock
}

@ActiveProfiles("specific-case-test") // This causes another Application Context to be created.
public class Test2 extends IntegrationTest {
  // Tests that use WireMock
}

public class Test3 extends IntegrationTest {
  // Tests that use WireMock
}

測試在所有這些場景中都成功運行:

  • 單獨運行測試
  • 按順序:Test1、Test3、Test2
  • 按順序:Test3、Test1、Test2
  • 按順序:Test2、Test3、Test1
  • 按順序:Test2、Test1、Test3

在所有這些情況下,最后一次運行的測試都失敗了:

  • 按順序:Test1、Test2、Test3
  • 按順序:Test3、Test2、Test1

我已經調查過這個問題,它與 Spring Application Context 和 WireMock 有關。

到底是怎么回事? 讓我們考慮測試按以下順序運行: Test1, Test2, Test3

Test1運行時,會創建一個應用程序上下文 (AC1) 並設置一個 WireMock 服務器 (WM1),比如說,在端口 1 上。端口 1 設置為 AC1 ( wiremock.server.port ) 並且 WM1 附加到測試線。 所有測試通過。

Test2運行時,會創建另一個應用程序上下文 (AC2) 並在端口 2 上設置新的 WireMock 服務器 (WM2)。端口 2 設置為 AC2 ( wiremock.server.port ),WM2 連接到測試線程,替換WM1。 所有測試通過。

Test3運行時,它會重用 AC1,這會導致測試失敗並顯示以下消息: 404 Not Found: [No response could be served as there are no stub mappings in this WireMock instance.] 應用程序狀態是wiremock.server.port為1(來自AC1)並且WM2 附加到測試線程。 正因為如此,對 WM2 進行了存根,但應用程序的其余調用將轉到 WM1,它正在偵聽端口 1。

我已經嘗試清理將@DirtiesContext添加到Test2 的應用程序上下文,因此它會強制Spring 加載第三個AC,但它不起作用。 但是,如果我將@DirtiesContext添加到 Test1 或將@DirtiesContext(classMode = BEFORE_CLASS)添加到 Test3 它可以工作。 我不想要這個解決方案,因為我有其他測試並且無法保證測試將以什么順序運行,所以如果我將它添加到 Test3,那么稍后執行順序將改變,另一個測試將失敗。 我想要一個真正的解決方案。

有任何想法嗎?

不確定您是否找到了解決方案,但這是我解決此問題的方法。

當彈簧緩存的測試上下文被重用時,wiremock 端口更改回該上下文端口,但似乎錯過了配置WireMock類默認服務器配置的某些步驟。 我們必須在@Before@BeforeEach方法中使用當前運行上下文的端口調用WireMock.configureFor(port) 這意味着當我們進行stubFor方法調用時,正確的 WireMock 端口被命中,並且服務器正確配置了我們的存根,請確保在任何重置之前也進行此配置。

@Autowired
private Environment environment;

private String getWiremockServerPort() {
    // Get the auto configured port property from the current Spring contexts environment
    return environment.getProperty("wiremock.server.port");
}

@BeforeEach
private void configureWireMockPortToMatchEnvironmentContext() {
    int contextEnvironmentPort = Integer.parseInt(getWiremockServerPort());
    configureFor(contextEnvironmentPort);
}

如果您以這種方式創建 Wiremock 存根:

stubFor(post(urlEqualTo(CALLBACK))
        .willReturn(aResponse().withStatus(202))
);

在使用來自 com.github.tomakehurst.wiremock.client.Wiremock 的靜態方法“stubFor”的地方,您可以嘗試在您的測試類中添加一個自動裝配的 WiremockServer 對象:

@Autowired
protected WireMockServer wireMockServer;

然后將您的存根創建替換為:

wireMockServer.stubFor(post(urlEqualTo(CALLBACK))
        .willReturn(aResponse().withStatus(202))
);

其中使用了來自 com.github.tomakehurst.wiremock.WireMockServer 的非靜態方法。

就我而言,這解決了問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM