解析已在Spring启动测试中使用的端口DEFINED PORT

yduiuuwa  于 2022-11-29  发布在  Spring
关注(0)|答案(3)|浏览(182)

我有一个Spring启动应用程序,它启动并执行一个类,该类侦听Application Ready事件以调用外部服务来获取一些数据,然后使用这些数据将一些规则推送到类路径以供执行。对于本地测试,我们模拟了应用程序中的外部服务,该服务在应用程序启动期间工作正常。

问题是在测试应用程序时出现的,方法是使用spring boot test注解和嵌入式jetty容器在以下位置运行应用程序:

  • 随机端口
  • 定义的端口

RANDOM PORT 的情况下,在应用程序启动时,它在定义的端口从属性文件中获取模拟服务的url,并且由于它是随机获取的,因此不知道嵌入式容器在哪里运行,因此无法给出响应。
DEFINED PORT 的情况下,对于第一个测试用例文件,它成功运行,但在拾取下一个文件时,它失败,表示端口已在使用中。
测试用例在逻辑上被划分为多个文件,并且需要在容器开始加载规则之前调用外部服务。
我如何在使用定义的端口的情况下在测试文件之间共享嵌入的容器,或者如何重构我的应用程序代码,以在测试用例执行期间启动时获得随机端口。
任何帮助都将不胜感激。

应用程序启动代码:

@Component
public class ApplicationStartup implements ApplicationListener<ApplicationReadyEvent> {

@Autowired
private SomeService someService;

@Override
public void onApplicationEvent(ApplicationReadyEvent arg0) {

    try {
        someService.callExternalServiceAndLoadData();
    }
    catch (Execption e) {}
    }
 }

测试代码注解:测试1

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@TestPropertySource("classpath:test-application.properties")
public class Test1 {

    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    public void tc1() throws IOException {.....}

测试代码注解:测试2

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@TestPropertySource("classpath:test-application.properties")
public class Test2 {

    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    public void tc1() throws IOException {.....}
kt06eoxx

kt06eoxx1#

如果您坚持在多个测试中使用相同的端口,您可以通过使用以下内容注解您的testclass来防止spring缓存上下文以用于进一步的测试:@脏上下文
在您的情况下:

@RunWith(SpringRunner.class)
@DirtiesContext
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@TestPropertySource("classpath:test-application.properties")

以下是Andy Wilkinson在this discussion上回答的一段话
Spring框架的测试框架在默认情况下,缓存上下文,以便多个测试类可能重用您有两个配置不同测试(由于@TestPropertySource),因此它们将使用不同的应用程序上下文。第一个测试的上下文将被缓存,并在第二个测试运行时保持打开状态。两个测试都被配置为对Tomcat的连接器使用相同的端口。因此,在运行第二个测试时,由于端口与第一个测试中的连接器冲突,上下文无法启动。您有以下几种选择:
1.使用随机端口
1.从Test 2移除@TestPropertySource,让内容具有相同的组态,而且第一个测试的内容可以重复用于第二个测试。
1.使用@DirtiesContext以便不缓存上下文

bakd9h0s

bakd9h0s2#

我遇到了同样的问题。我知道这个问题有点老了,但这可能会有所帮助:
使用@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)的测试也可以使用@LocalServerPort注解,将实际的连接埠插入字段,如下列范例所示:
来源:https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#howto-user-a-random-unassigned-http-port
给出的代码示例如下:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
public class MyWebIntegrationTests {

    @Autowired
    ServletWebServerApplicationContext server;

    @LocalServerPort
    int port;

    // ...

}
hmmo2u0o

hmmo2u0o3#

中application.properties
服务器端口=0
将在随机端口中运行应用程序

相关问题