如何测试EntityManager.persist()调用

时间:2013-10-22 10:19:38

标签: java spring configuration transactions spring-transactions

我在Spring Container中进行了一个简单的测试:

public class JpaCategoryRepositoryTest extends AbstractJpaJavaTestBase {

    @Inject
    private CategoryService categoryService;

    @Test
    public void testStoreCategory(){
        final Category category = new CategoryBuilder()
                .name("Test category")
                .build();
        assertEquals("Cateogory ID is not assigned", 0L, category.getId());
        categoryService.storeCategory(category);
        assertNotEquals("Category ID is persistent", 0L, category.getId());
    }
}

assertNotEquals失败。我认为该交易尚未提交。好的,我已经更新了添加transactio管理的测试:

public class JpaCategoryRepositoryTest extends AbstractJpaJavaTestBase {

    @Inject
    private CategoryService categoryService;

    @Inject
    TransactionTemplate transactionTemplate;

    @Test
    public void testStoreCategory(){
        final Category category = new CategoryBuilder()
                .name("Test category")
                .build();
        assertEquals("Cateogory ID is not assigned", 0L, category.getId());
        transactionTemplate.execute(new TransactionCallback<Void>() {
            @Override
            public Void doInTransaction(TransactionStatus status) {
                categoryService.storeCategory(category);
                return null;
            }
        });
        assertNotEquals("Category ID is persistent", 0L, category.getId());
    }
}

但它没有帮助。 在集成测试期间测试实体已被保存的最佳模式是什么?当我在测试失败后检查表时,保存实际实体。

2 个答案:

答案 0 :(得分:1)

在JPA规范中,只要设置了实体的ID,就可以使用JPA实现。但是,必须在将实体写入数据库时​​进行设置。您可以通过调用entityManager.flush()来强制执行此操作。所以在测试中添加一个entityManager:

@PersistenceContext
private EntityManager entityManager;

并在存储实体后调用flush():

categoryService.storeCategory(category);
entityManager.flush();

应该修复你的测试。

另请参阅:When does the JPA set a @GeneratedValue @Id

答案 1 :(得分:0)

目前我找不到解决方案来获取刚刚持有的实体的ID。它可能取决于id生成策略,jpa提供程序等。

为了测试实体是否持久化,我在测试之前和事务提交之后检查数字或记录。测试现在看起来像:

@Inject
private CategoryService categoryService;

@PersistenceContext
private EntityManager entityManager;

@Inject
TransactionTemplate transactionTemplate;

@Test
public void testStoreCategory(){
    final Category category = new CategoryBuilder()
            .name("Test category")
            .build();
    assertEquals("The number of test categories loaded during initial setup is incorrect",
            1, entityManager.createQuery("SELECT c FROM Category c").getResultList().size());
    assertEquals("Cateogory ID is not assigned", 0L, category.getId());
    transactionTemplate.execute(new TransactionCallbackWithoutResult() {
        @Override
        protected void doInTransactionWithoutResult(TransactionStatus status) {
            categoryService.storeCategory(category);
        }
    });
    assertEquals("The test category has not been persisted",
            2, entityManager.createQuery("SELECT c FROM Category c").getResultList().size());
}