如何正确停止并启动localstack实例

发布于 2025-02-12 10:02:17 字数 5105 浏览 3 评论 0原文

我正在使用LocalStack编写集成测试。我要测试的方案之一是何时AWS服务引发错误。我的测试看起来像是


    void saveEventsAsync_snsError() throws Exception{

       
        localSns.stop();

        mvc.perform( MockMvcRequestBuilders
                        .post("/events-async")
                        .content(validRequest())
                        .contentType(MediaType.APPLICATION_JSON)
                        .accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isInternalServerError());


    }

这样做会互相互相测试,而错误。大概是在测试运行时开始的容器。 我在这里有什么选择?使用localsns.isrunning() loping; t; t似乎

在这里有帮助的完整测试CLA以供参考

package ....

import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;
import org.springframework.http.MediaType;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.testcontainers.containers.localstack.LocalStackContainer;
import org.testcontainers.containers.wait.strategy.DockerHealthcheckWaitStrategy;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.DockerImageName;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sns.SnsClient;
import software.amazon.awssdk.services.sns.model.CreateTopicRequest;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.testcontainers.containers.localstack.LocalStackContainer.Service.SNS;

@SpringBootTest
@AutoConfigureMockMvc
@ActiveProfiles("test")
@Testcontainers
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class EventReportingControllerTest {

    @Autowired
    MockMvc mvc;

    @Container
    private static final LocalStackContainer localSns =
            new LocalStackContainer(DockerImageName.parse("localstack/localstack:0.11.3"))
                    .withServices(SNS);

    private static SnsClient snsClient;

    private static String topicArn ;

    @BeforeAll
    static void beforeAll() {
        localSns.start();

        snsClient = SnsClient.builder()
                .endpointOverride(localSns.getEndpointOverride(SNS))
                .credentialsProvider(
                        StaticCredentialsProvider.create(
                                AwsBasicCredentials.create(localSns.getAccessKey(), localSns.getSecretKey())
                        )
                )
                .region(Region.of(localSns.getRegion()))
                .build();

        topicArn = snsClient.createTopic(CreateTopicRequest.builder().name("testTopic").build()).topicArn();
    }

    @DynamicPropertySource
    public static void overrideProps(DynamicPropertyRegistry registry){
        registry.add("events.sns.topic.arn", () -> snsClient.createTopic(CreateTopicRequest.builder().name("testTopic").build()).topicArn());
    }

    @TestConfiguration
    public static class SnsClientConfig {
        @Bean
        @Profile("test")
        public SnsClient amazonSNSClient() {
            return snsClient;
        }
    }

    @Test
    void saveEventsAsync_success() throws Exception{
        mvc.perform( MockMvcRequestBuilders
                        .post("/events-async")
                        .content(validRequest())
                        .contentType(MediaType.APPLICATION_JSON)
                        .accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isAccepted()
                );
    }

    @Test
  
    void saveEventsAsync_invalidRequest() throws Exception{
        mvc.perform( MockMvcRequestBuilders
                        .post("/events-async")
                        .content(invalidRequest())
                        .contentType(MediaType.APPLICATION_JSON)
                        .accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isBadRequest());
    }

    @Test
    void saveEventsAsync_snsError() throws Exception{

    
        localSns.stop();
        mvc.perform( MockMvcRequestBuilders
                        .post("/events-async")
                        .content(validRequest())
                        .contentType(MediaType.APPLICATION_JSON)
                        .accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isInternalServerError());


    }

   
}

I am using Localstack to write integration tests. One of the scenarios I want to test is when the AWS service throws error. My test looks like


    void saveEventsAsync_snsError() throws Exception{

       
        localSns.stop();

        mvc.perform( MockMvcRequestBuilders
                        .post("/events-async")
                        .content(validRequest())
                        .contentType(MediaType.APPLICATION_JSON)
                        .accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isInternalServerError());


    }

However doing do fails one another test with HttpConnection refused.. error. Presumably the container didn't start by the time the test ran.
What are my options here ? Looping with localSns.isRunning() doesn;t seem to help

Here's full test clas for reference

package ....

import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;
import org.springframework.http.MediaType;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.testcontainers.containers.localstack.LocalStackContainer;
import org.testcontainers.containers.wait.strategy.DockerHealthcheckWaitStrategy;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.DockerImageName;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sns.SnsClient;
import software.amazon.awssdk.services.sns.model.CreateTopicRequest;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.testcontainers.containers.localstack.LocalStackContainer.Service.SNS;

@SpringBootTest
@AutoConfigureMockMvc
@ActiveProfiles("test")
@Testcontainers
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class EventReportingControllerTest {

    @Autowired
    MockMvc mvc;

    @Container
    private static final LocalStackContainer localSns =
            new LocalStackContainer(DockerImageName.parse("localstack/localstack:0.11.3"))
                    .withServices(SNS);

    private static SnsClient snsClient;

    private static String topicArn ;

    @BeforeAll
    static void beforeAll() {
        localSns.start();

        snsClient = SnsClient.builder()
                .endpointOverride(localSns.getEndpointOverride(SNS))
                .credentialsProvider(
                        StaticCredentialsProvider.create(
                                AwsBasicCredentials.create(localSns.getAccessKey(), localSns.getSecretKey())
                        )
                )
                .region(Region.of(localSns.getRegion()))
                .build();

        topicArn = snsClient.createTopic(CreateTopicRequest.builder().name("testTopic").build()).topicArn();
    }

    @DynamicPropertySource
    public static void overrideProps(DynamicPropertyRegistry registry){
        registry.add("events.sns.topic.arn", () -> snsClient.createTopic(CreateTopicRequest.builder().name("testTopic").build()).topicArn());
    }

    @TestConfiguration
    public static class SnsClientConfig {
        @Bean
        @Profile("test")
        public SnsClient amazonSNSClient() {
            return snsClient;
        }
    }

    @Test
    void saveEventsAsync_success() throws Exception{
        mvc.perform( MockMvcRequestBuilders
                        .post("/events-async")
                        .content(validRequest())
                        .contentType(MediaType.APPLICATION_JSON)
                        .accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isAccepted()
                );
    }

    @Test
  
    void saveEventsAsync_invalidRequest() throws Exception{
        mvc.perform( MockMvcRequestBuilders
                        .post("/events-async")
                        .content(invalidRequest())
                        .contentType(MediaType.APPLICATION_JSON)
                        .accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isBadRequest());
    }

    @Test
    void saveEventsAsync_snsError() throws Exception{

    
        localSns.stop();
        mvc.perform( MockMvcRequestBuilders
                        .post("/events-async")
                        .content(validRequest())
                        .contentType(MediaType.APPLICATION_JSON)
                        .accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isInternalServerError());


    }

   
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浅唱ヾ落雨殇 2025-02-19 10:02:17

使用@TestConainers@Container用于您的设置时,TestContainers将为您管理容器的生命周期。

因此,您目前有自我束缚和“由测试范围管理”的混合。

如果您想接管生命周期处理,请删除两个注释,然后根据自己的喜好启动/停止容器。

PS:如果您使用的是最近的Spring Cloud AWS版本,则覆盖AWS SDK客户端现在更简单

When using @Testconainers and @Container for your setup, Testcontainers will manage the lifecycle of the container for you.

Hence, you currently have a mix of self-manging and "managed by Testcontainers".

If you want to take over the lifecycle handling, remove the two annotations and start/stop the container according to your preference.

PS: If you're using a recent Spring Cloud AWS version, overriding the AWS SDK client is way simpler now.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文