使用 Spring Boot 测试容器和微服务

问题描述 投票:0回答:1

我有 2 个微服务:

服务 A 有一个端点来创建

Article
实体。该实体具有
Supplier
等属性。创建
Article
时,相应的方法从 Service B 调用(使用 Feign)端点,该端点返回
Supplier
(如果存在)。

@Getter
@Setter
@NoArgsConstructor
@Entity
@EqualsAndHashCode
@Table(name = "article")
public class ArticleDAO {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;

    @Column(name = "name")
    private String name;

    ...

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "supplier_id", referencedColumnName = "id")
    private SupplierDAO supplier;
}

创建文章的代码:

@Override
    public Article createArticle(final Article article, final String usuario) {
        final List<ArticleDAO> articleDAOS;
        
        if(this.suppliersFeignClient.getSupplier(article.getSupplier().getId().getBody() == null)
                // do something
        this.checkArticleDontExistByName(article);
        articles.forEach(article -> article.setUser(usuario));
        articleDAOS = this.modelMapper.map(articles, new TypeToken<List<ArticleDAO>>(){}.getType());
        this.articleRepository.saveAll(articleDAOS);
        return this.modelMapper.map(articleDAOS, new TypeToken<List<Article>>(){}.getType());
    }

在这里,我没有找到连接服务 A 和服务 B 的方法,两者都运行数据库进行集成测试,因为两者都使用 mysql。我需要服务 A 使用 TestContainers 运行 mysql 容器,还需要运行服务 B,服务 B 也需要自己的 mysql 容器。

我正在学习微服务的集成测试,在我的旅程中,我发现了 TestContainers 库,我设法使用 mysql 映像编写测试,但无需与其他微服务交互。现在我有 2 个微服务,我根本不知道如何为此编写测试,因为服务 B 也使用 mysql。

任何人都可以给我任何关于如何实现这一目标的指导吗?当有多个服务时,TestContainers 是否不适合集成测试?

我知道这个问题可能有点棘手,如果需要,我会添加更多信息或代码,但到目前为止,我只是在我的集成测试中添加了这个,如果我发表评论,它会完美地工作

this.suppliersFeignClient.getSupplier(article.getSupplier().getId().getBody() == null

    @ServiceConnection
    @Container
    private static final MySQLContainer<?> mySQLContainer = new MySQLContainer<>(ContainersConstants.MYSQL_CONTAINER_TAG);
    @Autowired
    private TestRestTemplate restTemplate;
    @Autowired
    private ArticlesService articlesService;
    @Autowired
    private ModelMapper modelMapper;
    @Autowired
    private ArticleRepository articleRepository;

    @BeforeAll
    static void beforeAll() {
        mySQLContainer.start();
    }



    @AfterAll
        static void afterAll() {
            mySQLContainer.stop();
        }

    @Test
    @DisplayName("Create articles /articles")
    void WHEN_calling_create_articles_THEN_status_is_200() {
        final List<ArticleDTO> articleDTOS = Instancio.ofList(ArticleDTO.class).size(3)
                .ignore(field(ArticleDTO::getId))
                .ignore(field(ArticleDTO::getCategory))
                .ignore(field(ArticleDTO::getSupplier))
                .create();
        final CreateArticlesRequest createArticlesRequest = CreateArticlesRequest.builder()
                .articles(articleDTOS)
                .user(Instancio.create(String.class))
                .build();
        final ResponseEntity<CreateArticlesResponse> response = restTemplate.exchange(restTemplate.getRootUri() + URIConstants.ARTICLES_URI,
                HttpMethod.POST, new HttpEntity<>(createArticlesRequest), new ParameterizedTypeReference<>() {});
        final List<ArticleDTO> articles = Objects.requireNonNull(response.getBody()).getArticles();

        articles.forEach(article -> article.setId(null));

        assertEquals(articles.size(), articleDTOS.size() , "articles.size() should be " + articleDTOS.size());
        assertTrue(articles.containsAll(articleDTOS), "articles should contain the same elements as articulosDTOS");
        assertEquals(HttpStatus.OK, response.getStatusCode(), "Status Code should be " + HttpStatus.OK);
    }

谢谢

mysql spring-boot microservices testcontainers
1个回答
0
投票

如果您想让每个服务都有自己的数据库,并且在同一台计算机上运行它们,则需要为每个容器使用不同的端口。

要进行集成测试,您需要提供其他服务的主机和端口并向其发送请求,在您的代码中,您将请求发送到运行测试的同一服务。

© www.soinside.com 2019 - 2024. All rights reserved.