ricardo-bernardes/springtest-service-generator icon
public
Published on 7/2/2025
Spring Boot Integration Test Generator

Prompts
GenerateSpringBootIntegrationTest
Gera uma classe de teste de integração completa para um Service do Spring Boot, seguindo as melhores práticas com JUnit 5, scripts SQL e Mocks.
Aja como um desenvolvedor Java Sênior, especialista em testes de integração com Spring Boot e JUnit 5. Seu objetivo é gerar uma classe de teste completa para o serviço `{{ServiceClassName}}`, seguindo rigorosamente a estrutura, convenções e estilo descritos abaixo. O teste deve interagir com um banco de dados em memória (H2) populado por scripts SQL.
**1. Estrutura Fundamental da Classe** - **Pacote:** `{{TestPackage}}` - **Nome da Classe:** `{{ServiceClassName}}IT` (use o sufixo 'IT' para testes de integração). - **Cabeçalho Obrigatório:** Inclua o seguinte cabeçalho de copyright. ```java /*
 * Copyright (c) {{YEAR}}, {{COMPANY}}. All rights reserved.
 */
``` - **Anotações da Classe:**
  - Use `@ServicesTest` (ou anotação customizada para testes de serviço).
  - Use `@Import` para incluir a classe de serviço sendo testada (`{{ServiceClassName}}.class`) e quaisquer DTO Assemblers necessários (`{{ImportedAssemblers}}`).

**2. Injeção de Dependências** - **`@Autowired`:** Use para injetar beans reais do contexto Spring que são necessários para o teste, como o serviço alvo, repositórios, `ModelMapper`, e DTO Assemblers.
  - Dependências a injetar: `{{AutowiredDependencies}}`.
- **`@MockBean`:** Use para mockar serviços externos ou dependências cujo comportamento precisa ser controlado (ex: serviços de pagamento, notificação, APIs de terceiros).
  - Dependências a mockar: `{{MockedDependencies}}`.

**3. Configuração do Ambiente de Teste (Setup)** - **`@BeforeAll` (Setup do Banco de Dados):**
  - Crie um método `static void` anotado com `@BeforeAll`.
  - O método deve receber `DataSource` como parâmetro.
  - Use `ScriptUtils.executeSqlScript` para executar os scripts SQL na seguinte ordem: primeiro os de domínio/suporte (`{{OtherSqlScripts}}`), depois o principal (`{{MainSqlScript}}`).
- **`@BeforeEach` (Setup por Teste):**
  - Crie um método `void` anotado com `@BeforeEach`.
  - Neste método, carregue entidades do banco de dados (que foram inseridas pelo `@BeforeAll`) e armazene-as em variáveis de instância da classe de teste. Isso garante que cada teste comece com um estado limpo e conhecido.
  - Implemente o seguinte bloco de código:
  ```java
  {{BeforeEachSetupCode}}
  ```

**4. Estrutura e Padrões dos Métodos de Teste** - **Convenção de Nomes:** Siga estritamente o padrão `metodoTestado_QuandoCondicao_DeveComportamentoEsperado()`. - **Corpo do Teste:** Utilize o padrão **Arrange-Act-Assert**. - **Asserções:** Use as asserções do `org.junit.jupiter.api.Assertions` (`assertEquals`, `assertNotNull`, `assertThrows`, etc.). - **Linguagem:** Todo o código, comentários e nomes de variáveis devem ser em português.
**5. Cenários de Teste a Serem Gerados** Gere os métodos de teste para os seguintes cenários, usando os placeholders de exceções e DTOs fornecidos.
**a) Testes de Recuperação (GET):** - `buscarPorId_QuandoIdNaoExiste_DeveLancar{{NotFoundException}}` - `buscarPorId_Quando{{EntityName}}PertenceAOutraLoja_DeveLancar{{NotFoundException}}` - `buscarPorId_Quando{{EntityName}}FoiExcluidoLogicamente_DeveLancar{{NotFoundException}}` - `buscarPorId_QuandoIdValido_DeveRetornar{{ResponseDtoName}}Corretamente`
**b) Testes de Criação (CREATE):** - `criar_QuandoDadosValidos_DeveSalvarComSucesso` - `criar_QuandoNomeJaExisteNaMesmaLoja_DeveLancar{{BusinessException}}ComMensagemEspecifica` (Mensagem: `{{UniqueConstraintMessage}}`) - `criar_QuandoForeignKeyInvalida_DeveLancar{{ForeignKeyException}}` - `criar_QuandoNomeDuplicadoEmOutraLoja_DeveSalvarComSucesso`
**c) Testes de Atualização (UPDATE):** - `atualizar_QuandoDadosValidos_DeveAlterarNoBanco` - `atualizar_Quando{{EntityName}}PertenceAOutraLoja_DeveLancar{{NotFoundException}}`
**d) Testes de Remoção (DELETE / Soft-Delete):** - `remover_Quando{{EntityName}}Valido_DevePreencherDataExclusao` - `remover_Quando{{EntityName}}NaoExiste_DeveLancar{{NotFoundException}}`
**Exemplo de Estrutura Final:** ```java package {{TestPackage}};
// imports... import static org.junit.jupiter.api.Assertions.*;
@ServicesTest @Import({{{ServiceClassName}}.class, {{ImportedAssemblers}}}) class {{ServiceClassName}}IT {

    @Autowired
    private {{ServiceClassName}} {{serviceInstanceName}};

    // Outras dependências com @Autowired
    // {{AutowiredDependencies declarations}}

    // Mocks
    // {{MockedDependencies declarations}}

    // Variáveis de instância para dados de setup
    // {{InstanceVariablesForSetup}}

    @BeforeAll
    static void setupDatabase(@Autowired DataSource dataSource) {
        // Executar scripts SQL
    }

    @BeforeEach
    void setupTestData() {
        // Carregar dados dos repositórios para as variáveis de instância
        {{BeforeEachSetupCode}}
    }

    @Test
    @DisplayName("Deve lançar {{NotFoundException}} ao buscar por ID inexistente")
    void buscarPorId_QuandoIdNaoExiste_DeveLancar{{NotFoundException}}() {
        // Arrange
        Long idInexistente = 999L;

        // Act & Assert
        assertThrows({{NotFoundException}}.class, () -> {
            {{serviceInstanceName}}.buscarPorId(idInexistente);
        });
    }

    @Test
    @DisplayName("Deve salvar com sucesso um novo {{entityNameLower}} com dados válidos")
    void criar_QuandoDadosValidos_DeveSalvarComSucesso() {
        // Arrange
        var requestDTO = new {{RequestDtoName}}();
        // ... popular DTO com dados válidos

        // Act
        var responseDTO = {{serviceInstanceName}}.criar(requestDTO);

        // Assert
        assertNotNull(responseDTO);
        assertNotNull(responseDTO.getId());
        // ... outras asserções
    }

    // ... outros métodos de teste seguindo a estrutura ...
} ```