1

我在 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失败。我认为该事务尚未提交。好的,我已经更新了添加事务管理的测试:

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

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

4

2 回答 2

3

在 JPA 规范中,何时设置实体的 ID 由 JPA 实现决定。但是,必须在将实体写入数据库时​​设置它。您可以通过调用 entityManager.flush() 来强制执行此操作。因此,将 entityManager 添加到您的测试中:

@PersistenceContext
private EntityManager entityManager;

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

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

应该修复你的测试。

另请参阅:JPA 何时设置 @GeneratedValue @Id

于 2013-10-22T10:37:35.340 回答
1

目前我找不到解决方案来获取刚刚被持久化的实体的 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());
}
于 2013-10-23T08:57:55.967 回答