SpringBoot-Não use @Transactional nos testes de integração do Spring Boot

Quando o teste está em execução, as @Transactional anotações na classe de teste  farão com que Entity a operação dos dados no teste  seja concluída na memória e, eventualmente, a commit operação não será  executada, ou seja, os Entity dados não serão  persistidos, resultando no comportamento e na aplicação real do teste. O comportamento de S é inconsistente.

O gerenciamento de transações é um design indispensável no desenvolvimento de aplicativos e é um padrão para o processamento de persistência do banco de dados. Sabemos que o desenvolvimento de aplicativos é inseparável dos dados CRUD(adição, exclusão, modificação e inspeção), e a ACIDnatureza da transação pode garantir melhor a integridade dos dados e dos dados relacionados 同生共死. O ciclo de vida de uma única transação é dividido principalmente em três estágios, BEGIN TRANSACTION ->  COMMIT TRANSACTION ->  ROLLBACK TRANSACTION.

Spring BootO uso de transações é dividido em imperativo e declarativo, e a maneira comum é a anotação declarativa ( @Transactional). O gerenciamento de transações pode ser usado na camada de aplicativos e nos testes.

Para garantir a independência entre os testes, os dados entre os testes não serão afetados um pelo outro. Talvez você tenha escrito um teste como este:

@SpringBootTest
@ActiveProfiles("test")
@Transactional
public class UserControllerTest { }

@Transactional Ao truncar a operação de persistência de dados, é resolvido o problema de que os testes se opõem e os dados não se afetam. No entanto, esse método tem efeitos colaterais , ou seja, o processo de persistência de dados não é mais verdadeiro e o processo se foi commit. Isso leva a:

  • Não há garantia  Entity da relação entre a associação, a precisão da associação entre o índice exclusivo e a chave estrangeira primária
  • Não é possível garantir a precisão do  Entity tempo de criação, do tempo de atualização e da lógica de atribuição com versão (bloqueio otimista)
  • Nós não podemos garantir que  Entity não há  @Transient uma atribuição de precisão atributo anotação lógica
  • Os dados do teste não são um problema na cena real
  • No teste, os dados preparados em uma única transação não podem ser compartilhados entre vários encadeamentos.

......

Então,  qual é a intenção original de Spring introduzir o gerenciamento de transações no domínio do problema de teste ? Para resolver que problema é necessário apresentá-lo? O documento oficial apresenta o  gerenciamento de transações

Descrição da imagem

De acordo com a documentação oficial, para resolver a execução do teste, o programa acessa o banco de dados real e altera o estado dos dados, o que afeta os problemas subsequentes do teste.

De fato, aqui deve haver um pensamento crítico , por que você precisa acessar o banco de dados real quando o teste é executado? Por que os dados entre os testes se afetam?
Para cada teste, deve haver um contexto limpo antes de cada execução, ou um contexto independente, existe um processo de limpeza e preparação de dados e os testes são isolados um do outro. Ou seja, por que o teste não pode usar banco de dados na memória ou banco de dados incorporado? Por que não limpar os dados no banco de dados antes de cada execução de teste para garantir que a terra pura antes da execução do caso de teste não seja afetada pelos dados de teste anteriores?

A resposta é, claro ! ! !

 

Escreva no final

Como fazer isso? Implemente um  TruncateDatabaseService, exclua apenas os dados da tabela, não exclua o resultado da tabela. Na classe base de teste @BeforeEach, execute  truncate. Banco de dados truncado de origem :

Publicado 952 artigos originais · elogiado 1820 · 890.000 visualizações

Acho que você gosta

Origin blog.csdn.net/Dream_Weave/article/details/105373383
Recomendado
Clasificación