如何在测试之间重置

时间:2016-12-12 00:31:55

标签: java spring spring-boot spring-data-jpa junit4

我有一个测试类

@RunWith(SpringRunner.class)
@DataJpaTest

我有两个测试。在每个测试中我都做同样的操作,坚持对象。只有查找电话不同。

如果我同时运行两个测试,他们会失败,但如果我一个接一个地进行测试,他们就会成功。

每次测试之间没有重置。怎么做?在每个测试中,只有对存储库的调用是不同的。

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

}

修改

我把所有代码:http://pastebin.com/M9w9hEYQ

8 个答案:

答案 0 :(得分:17)

添加@DirtiesContext注释,但为其提供 AFTER_EACH_TEST_METHOD classMode

@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)

答案 1 :(得分:10)

在每种测试的情况下,您都会保留相同的数据。因此,您应该在所有测试之前保留数据,或者在每次测试之前保留数据并在之后进行清理。

<强> 1。在所有测试前坚持

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

在这种情况下,@ AfterClass可选

<强> 2。每次测试前坚持并在每次测试后清洁

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

请记住,使用@BeforeClass和@AfterClass的方法必须是静态的。

答案 2 :(得分:7)

您可以在测试类上使用@DirtiesContext注释来重置测试,您也可以选择何时重置。默认值是在每个方法之后,但您可以通过将不同的参数传递给@DirtiesContext注释来更改它。

import org.springframework.test.annotation.DirtiesContext;

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

答案 3 :(得分:3)

将@Sql与ExecutionPhase.AFTER_TEST_METHOD一起使用并传递用于清理数据库的脚本

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

如果您使用@Transactional注释,可以使用:

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

答案 4 :(得分:2)

您是否尝试清除每个测试之间的持久性缓存 TestEntityManager#clear()

                 DB1 ------> DB2 ------> DB3 --
                  |                            |
                   ------------<---------------

或者尝试将@After public void clear() { this.entityManager.clear(); } 设置为字段并将其删除,而不是刷新更改:

Visitor

答案 5 :(得分:1)

在测试类顶部使用@Transactional(propagation = Propagation.REQUIRES_NEW),它将在每个方法之后显式请求创建新事务

答案 6 :(得分:0)

@DirtiesContext(classMode =DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) 适用于我,但只有当我使用@DataJpaTest()运行@AutoConfigureTestDatabase(replace=Replace.NONE)和mysql的costum配置文件时,默认h2才能运行。

答案 7 :(得分:0)

尽管已为您解决了此问题,但我只想指出,由于我的h2有一个data.sql初始化(默认情况下会创建一个用户),因此清除存储库无法满足我的特定用例我必须在src / test / resources下添加一个具有以下属性的application.properties文件:

spring.datasource.initialization-mode =从不

参考提出该建议的话题: Spring Boot ignore data.sql when running unit tests