How to reset between tests

33,388

Solution 1

Add the @DirtiesContext annotation, but provide it with the AFTER_EACH_TEST_METHOD classMode

@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)

Solution 2

In your case for each test you persist the same data. So you should persist data before all test or persist before each test and clean after it.

1. Persist before all test

@BeforeClass
public static void init(){
  //persist your data
}

@AfterClass
public static void clear(){
  //remove your data
}

@Test
public void findTopByCommerceCommerceIdOrderByEntryTimeDesc() {
    Visit visit = visitRepository.findTopByCommerceCommerceIdOrderByEntryTimeDesc(commerceId);

    assertEquals(visit.getVisitId(), Long.valueOf("1"));
}

In this case @AfterClass is optionally

2. Persist before each test and clean after each test

    @Before
    public void init(){
      //persist your data
    }

    @After
    public void clear(){
      //remove your data
    }

    @Test
    public void findTopByCommerceCommerceIdOrderByEntryTimeDesc() {
        Visit visit = visitRepository.findTopByCommerceCommerceIdOrderByEntryTimeDesc(commerceId);

        assertEquals(visit.getVisitId(), Long.valueOf("1"));
    }

Remember that methods which use @BeforeClass and @AfterClass must be static.

Solution 3

You can use @DirtiesContext annotation on your test class to reset the tests, there you can also choose when to reset. Default is after every method, but you can change that by passing in different parameters to the @DirtiesContext annotation.

import org.springframework.test.annotation.DirtiesContext;

@RunWith(SpringRunner.class)
@DataJpaTest
@DirtiesContext
public class VisitRepositoryTest {

Solution 4

Use @Sql with ExecutionPhase.AFTER_TEST_METHOD and pass the script that is to be used to clean the database

@Sql(scripts="classpath:cleanup.sql",executionPhase=Sql.ExecutionPhase.AFTER_TEST_METHOD)
@Test
public void whateverIsYourTestMethod()
{
...
}

In case you are using @Transactional annotation , you can use :

@Sql(scripts="classpath:cleanup.sql",executionPhase=Sql.ExecutionPhase.AFTER_TEST_METHOD,config = @SqlConfig
        ( transactionMode = TransactionMode.ISOLATED,
        transactionManager = "transactionManager",
        dataSource= "dataSource" ))
@Test
@Commit
@Transactional
public void whateverIsYourTestMethod(){...}

Solution 5

Have you try to clear the peristence cache between each tests, according to TestEntityManager#clear()

@After
public void clear() {
    this.entityManager.clear();
}

Or maybe try to set your Visitor as fields and remove them in an after, than flush the changes :

Visit visit1;

Visit visit2;

@After
public void clear(){
  if (visit1 != null)
      this.entityManager.remove(visit1);
  if (visit2 != null)
      this.entityManager.remove(visit2);
  this.entityManager.flush();
}
Share:
33,388
robert trudel
Author by

robert trudel

Updated on August 01, 2020

Comments

  • robert trudel
    robert trudel almost 4 years

    I have a test class

    @RunWith(SpringRunner.class)
    @DataJpaTest
    

    I have two tests. In every test I do the same operation, persist the object. Only the find call are different.

    If I run both tests together they fail but if I run test one after another they are successful.

    There is no reset between each test. How to do that? Only the call to the repository is different in each test.

    @Test
    public void findTopByCommerceCommerceIdOrderByEntryTimeDesc() {
    
        Long commerceId = 1L;
    
        Commerce commerce = new Commerce();
        commerce.setName("test");
        this.entityManager.persist(commerce);
    
        Member member = new Member();
        member.setCommerce(commerce);
        member.setMan(true);
        member.setName("bob binette");
    
        this.entityManager.persist(member);
    
        Visit visit1 = new Visit();
        visit1.setCommerce(commerce);
    
        visit1.setMember(member);
        visit1.setEntryTime(LocalDateTime.of(LocalDate.now(), LocalTime.now()));
    
        Visit visit2 = new Visit();
        visit2.setCommerce(commerce);
    
        visit2.setMember(member);
        visit2.setEntryTime(LocalDateTime.of(LocalDate.now().minusDays(2), LocalTime.now()));
    
        this.entityManager.persist(visit1);
        this.entityManager.persist(visit2);
    
        Visit visit = visitRepository.findTopByCommerceCommerceIdOrderByEntryTimeDesc(commerceId);
    
        assertEquals(visit.getVisitId(), Long.valueOf("1"));
    
    }
    

    Edit

    i put all the code : http://pastebin.com/M9w9hEYQ