Em primeiro lugar, encontrei muitos tópicos no StackOverflow sobre isso, mas nenhum deles realmente me ajudou, então desculpe por fazer uma pergunta possivelmente duplicada.
Estou executando testes JUnit usando spring-test, meu código se parece com este
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {})
public class StudentSystemTest {
@Autowired
private StudentSystem studentSystem;
@Before
public void initTest() {
// set up the database, create basic structure for testing
}
@Test
public void test1() {
}
...
}
Meu problema é que eu quero que meus testes NÃO influenciem outros testes. Então, eu gostaria de criar algo como rollback para cada teste. Procurei muito por isso, mas não encontrei nada até agora. Estou usando Hibernate e MySql para isso
initTest
Respostas:
Basta adicionar uma
@Transactional
anotação no topo do seu teste:@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"testContext.xml"}) @Transactional public class StudentSystemTest {
Por padrão, o Spring irá iniciar uma nova transação envolvendo seu método de teste e
@Before
/@After
callbacks, revertendo no final. Funciona por padrão, basta ter algum gerenciador de transações no contexto.De: 10.3.5.4 Gestão de transações (negrito):
fonte
PlatformTransactionManager
. Caso contrário, como o Spring saberá sobre suas transações e banco de dados?@Transactional
no@Test
nível do método e não no nível da classe.À parte: a tentativa de alterar a resposta de Tomasz Nurkiewicz foi rejeitada:
Link correto e permanente para a seção relevante da documentação sobre o teste de integração.
fonte
As respostas que mencionam adição
@Transactional
estão corretas, mas para simplificar, você pode apenas ter sua aula de testeextends AbstractTransactionalJUnit4SpringContextTests
.fonte
Eu sei, estou muito tarde para postar uma resposta, mas espero que possa ajudar alguém. Além disso, acabei de resolver esse problema que tive com meus testes. Isso é o que eu tive em meu teste:
Minha aula de teste
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "path-to-context" }) @Transactional public class MyIntegrationTest
Context xml
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="${jdbc.driverClassName}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean>
Eu ainda tinha o problema de que o banco de dados não estava sendo limpo automaticamente.
O problema foi resolvido quando adicionei a seguinte propriedade a BasicDataSource
<property name="defaultAutoCommit" value="false" />
Espero que ajude.
fonte
Você precisa executar seu teste com um contexto Spring e um gerenciador de transações, por exemplo,
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"/your-applicationContext.xml"}) @TransactionConfiguration(transactionManager="txMgr") public class StudentSystemTest { @Test public void testTransactionalService() { // test transactional service } @Test @Transactional public void testNonTransactionalService() { // test non-transactional service } }
Consulte o capítulo
3.5.8. Transaction Management
de referência do Spring para obter mais detalhes.fonte
Além de adicionar
@Transactional
no@Test
método, você também precisa adicionar@Rollback(false)
fonte
Você pode desativar o Rollback:
@TransactionConfiguration(defaultRollback = false)
Exemplo:
@RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @Transactional @TransactionConfiguration(defaultRollback = false) public class Test { @PersistenceContext private EntityManager em; @org.junit.Test public void menge() { PersistentObject object = new PersistentObject(); em.persist(object); em.flush(); } }
fonte