如何在AbstractTransactionalJUnit4SpringContextTests测试中测试我的DAO更新方法?

时间:2019-02-25 16:46:20

标签: java spring hibernate junit transactions

我正在使用Java 8,JUnit 4.12,Spring 4和Hibernate 5.2.12.Final。我想测试一个Hibernate方法,在其中更新一些行。方法看起来像这样

        final CriteriaBuilder qb = m_entityManager.getCriteriaBuilder();
        final CriteriaUpdate<FailedEvent> q = qb.createCriteriaUpdate(FailedEvent.class);
        final Root<FailedEvent> root = q.from(FailedEvent.class);
        q.where(qb.and( qb.equal(root.get(FailedEvent_.objectId), objectId) ));
        q.set(root.get(FailedEvent_.flaggedForDelete), true);
        affectedRows = m_entityManager.createQuery(q).executeUpdate();
     return affectedRows > 0;

我进行了以下JUnit测试以验证这一点

public class FailedEventDaoTest extends AbstractTransactionalJUnit4SpringContextTests
...

    @Test
    public final void testFlagForDeleteByObjectId()
    {
            final String eventId = "testId";
            final FailedEvent event = failedEventDao.findByEventId(eventId);
            Assert.assertFalse("A pre-condition fo this test is that an failed_event record with id \"" + eventId + "\" have a non-empty object id.", StringUtils.isEmpty(event.getObjectId()));
            Assert.assertTrue(failedEventDao.flagForDeleteByObjectId(event.getObjectId()));
            final FailedEvent foundEvent = failedEventDao.findByEventId(eventId);
            Assert.assertTrue("Failed to mark flag for deletion.", foundEvent.getFlaggedForDelete());
    }   // testFlagForDeleteByObjectId

但是我的测试在最后一行失败

Assert.assertTrue("Failed to mark flag for deletion.", foundEvent.getFlaggedForDelete());

这是因为事务尚未完成,所以数据库中没有任何更新吗?我可以通过什么方式验证正确的记录?

2 个答案:

答案 0 :(得分:4)

尝试@AfterTransaction注释来测试结果。

    @AfterTransaction
    public final void theRealTest()
    {
            Assert.assertTrue("Failed to mark flag for deletion.", foundEvent.getFlaggedForDelete());
    }

https://www.springbyexample.org/examples/simple-spring-transactional-junit4-test-code-example.html

如果这也不起作用,请尝试:

  

“因此,您需要在测试方法内创建多个事务。   如您所见,您不能使用   AbstractTransactionalJUnit4SpringContextTests,因为它创建了一个   整个测试方法只能进行一次交易,不能裸露使用   AbstractJUnit4SpringContextTests,因为它不创建任何事务   完全没有。

     

解决方案是使用AbstractJUnit4SpringContextTests并进行管理   以编程方式在您的测试方法内进行交易。

     

您需要将PlatformTransactionManager注入测试中,然后创建   从中获取TransactionTemplate并使用它来划分交易   如11.6程序化交易管理中所述。”

在这里找到: Using AbstractTransactionalJUnit4SpringContextTests with commit halfway through

答案 1 :(得分:3)

您应该考虑不要扩展抽象类并使用其他方法。 例如

@RunWith(SpringJUnit4ClassRunner.class) 
@Transactional

在课堂上。

赞:

  package com.example;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

import com.example.model.Person;
import com.example.service.PersonService;

@RunWith(SpringJUnit4ClassRunner.class)
@Transactional
@ContextConfiguration("classpath:/spring-beans.xml")
public class PersonServiceIntegrationTests {
    @Autowired
    private PersonService personService;

    @Autowired
    private JdbcTemplate jdbcTemplate;


    @Test
    public void shouldCreateNewPerson() {
        Person person = new Person();
        person.setFirstName("Kenan");
        person.setLastName("Sevindik");

        long countBeforeInsert = jdbcTemplate.queryForObject("select count(*) from t_person", Long.class);
        Assert.assertEquals(2, countBeforeInsert);

        personService.create(person);

        long countAfterInsert = jdbcTemplate.queryForObject("select count(*) from t_person", Long.class);
        Assert.assertEquals(3, countAfterInsert);
    }

    @Test
    public void shouldDeleteNewPerson() {
        long countBeforeDelete = jdbcTemplate.queryForObject("select count(*) from t_person", Long.class);
        Assert.assertEquals(2, countBeforeDelete);

        personService.delete(1L);

        long countAfterDelete = jdbcTemplate.queryForObject("select count(*) from t_person", Long.class);
        Assert.assertEquals(1, countAfterDelete);
    }

    @Test
    public void shouldFindPersonsById() {
        Person person = personService.findById(1L);

        Assert.assertNotNull(person);
        Assert.assertEquals("John", person.getFirstName());
        Assert.assertEquals("Doe", person.getLastName());
    }
}

检查https://examples.javacodegeeks.com/enterprise-java/spring/write-transactional-unit-tests-spring/#section_7

  @RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(

  classes = { StudentJpaConfig.class }, 

  loader = AnnotationConfigContextLoader.class)

@Transactional

public class InMemoryDBTest {

     

    @Resource

    private StudentRepository studentRepository;

     

    @Test

    public void givenStudent_whenSave_thenGetOk() {

        Student student = new Student(1, "john");

        studentRepository.save(student);

         

        Student student2 = studentRepository.findOne(1);

        assertEquals("john", student2.getName());

    }

}

检查一下 https://www.baeldung.com/spring-jpa-test-in-memory-database