2016-12-12 38 views
12

Mam klasy testowejJak zresetować między testami

@RunWith(SpringRunner.class) 
@DataJpaTest 

mam dwa testy. W każdym teście wykonuję tę samą operację, utrzymuję obiekt. Tylko wywołanie find jest inne.

Jeśli oba testy wykonam razem, to się nie powieść, ale jeśli wykonuję test jeden po drugim, są skuteczne.

Po każdym teście nie ma resetowania. Jak to zrobić? Tylko wywołanie repozytorium jest inne w każdym teście.

@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 umieścić cały kod: http://pastebin.com/M9w9hEYQ

+2

Użyj JUnit ['@ Before'] (http://junit.sourceforge.net/javadoc/org/junit/Before.html) i [' @ After'] (http://junit.sourceforge.net/ javadoc/org/junit/After.html)? – manish

+0

Wykonując testy '@ Transactional'. –

+1

Testy 'DataJpaTest' są domyślnie transakcyjne Martijn. Coś innego dzieje się, czego nie widzimy: powinno to działać po wyjęciu z pudełka. –

Odpowiedz

8

W twoim przypadku dla każdego testu utrzymują te same dane. Dlatego powinieneś przechowywać dane przed każdym testem lub utrzymywać się przed każdym testem i wyczyścić po nim.

1. Utrzymywać przed całym badaniu

@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")); 
} 

W tym przypadku @AfterClass ewentualnie

2. Utrzymywać przed każdym badaniem i czyste po każdej próbie

@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")); 
    } 

Pamiętaj, że metody używające @BeforeClass i @AfterClass muszą być statyczne.

+0

Proponuję "@ Przed" i "@ Po". Zalecana praktyka: http://stackoverflow.com/a/14737697/5012277 –

+0

próbował dodać this.entityManager.remove (visit1); this.entityManager.remove (visit2); po twierdzeniu ... uzyskaj ten sam numer –

+0

Możesz dodać fragment. – marok

4

Możesz użyć adnotacji @DirtiesContext na swojej klasie testowej, aby zresetować testy, tam możesz także wybrać, kiedy chcesz zresetować. Domyślnie jest po każdej metodzie, ale możesz to zmienić, przekazując różne parametry do adnotacji @DirtiesContext.

import org.springframework.test.annotation.DirtiesContext; 

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

próbował dodać @DirtiesContext, ale mam ten sam problem. –

2

Czy spróbować wyczyścić pamięć podręczną peristence pomiędzy każdym testów według TestEntityManager#clear()

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

A może spróbuj ustawić swój Visitor jako pola i usunąć je w sposób później niż wylewać zmiany :

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(); 
} 
4

Dodaj adnotacji @DirtiesContext, ale dostarczają go z AFTER_EACH_TEST_METHOD classMode

@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) 
2

Użyj @Sql z ExecutionPhase.AFTER_TEST_METHOD i przekazać skrypt, który ma być używany do czyszczenia bazy danych

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

W przypadku korzystania @Transactional adnotacji, można użyć:

@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(){...} 
0

@DirtiesContext(classMode =DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) prace dla mnie, ale to jest konieczne tylko wtedy, gdy uruchamiam @DataJpaTest() z @AutoConfigureTestDatabase(replace=Replace.NONE) i profilem costum dla mysql, domyślnie h2 działa bez tego.