Java 使用WireMock的Spring JUnit测试中的多个应用程序上下文

Java 使用WireMock的Spring JUnit测试中的多个应用程序上下文,java,spring,spring-boot,integration-testing,wiremock,Java,Spring,Spring Boot,Integration Testing,Wiremock,我有以下情况: @Transactional @SpringBootTest @ActiveProfiles("test") @AutoConfigureMockMvc @AutoConfigureWireMock(port = 0) public abstract class IntegrationTest { } public class Test1 extends IntegrationTest { // Tests that use WireMock } @A

我有以下情况:

@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应用程序上下文和WireMock有关

发生了什么事?让我们考虑测试是按顺序运行的:<代码> TEST1、TEST2、Test3 < /P> 当
Test1
运行时,将创建一个应用程序上下文(AC1),并在端口1上设置一个WireMock服务器(WM1)。端口1设置为AC1(
wiremock.server.Port
),WM1连接到测试线程。所有测试都通过了

Test2
运行时,会创建另一个应用程序上下文(AC2),并在端口2上设置一个新的WireMock服务器(WM2)。端口2设置为AC2(
wiremock.server.Port
),WM2连接到测试线程,替换WM1。所有测试都通过了

当运行
Test3
时,它会重用AC1,这会导致测试失败,并显示以下消息:
404notfound:[无法响应,因为此WireMock实例中没有存根映射。]
。 应用程序状态为
wiremock.server.port
为1(来自AC1),WM2连接到测试线程。因此,对WM2进行存根,但应用程序rest调用将转到WM1,后者正在侦听端口1

我已经尝试将
@DirtiesContext
添加到Test2中来清理应用程序上下文,因此它将强制Spring加载第三个AC,但它不起作用。但是,如果我将
@DirtiesContext
添加到Test1或
@DirtiesContext(classMode=BEFORE\u CLASS)
添加到Test3,它就会工作。我不想要这个解决方案,因为我有其他的测试,并且不能保证测试的运行顺序,所以如果我将它添加到Test3中,那么稍后执行顺序将改变,另一个测试将失败。我想要一个真正的解决方案


有什么想法吗?

不确定您是否找到了解决方案,但下面是我如何解决的

当重新使用spring缓存的测试上下文时,wiremock端口将更改回该上下文端口,但似乎错过了配置
wiremock
classes默认服务器配置的某些步骤。我们必须在
@Before
@beforeach
方法中使用当前运行上下文的端口调用
WireMock.configureFor(port)
。这意味着,当我们执行
stubFor
方法调用时,正确的WireMock端口被命中,服务器正确地配置了stub,请确保在进行任何重置之前进行此配置

@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);
}

每个AC是否需要单独的WireMock实例?如果不是,你能启动一个单一的WireMock实例并让所有的ACs指向它吗?不,但是,@AutoConfigureWireMock就是这样工作的。它为每个AC创建了一个新的WM实例。我可以按照你的建议做,但是我必须自己控制一切,然后就没有必要使用注释了。如果我找不到解决方案,这将是我的出路。我只是停止使用注释并实现了我自己的解决方案,但是,您的建议确实解决了问题。