如何使用 Spring 自动装配来概括 JMockit 测试
How to generalize a JMockit test using Spring autowiring
所以我想对几种不同的 Dao 方法使用通用测试。在 Dao 内部,我将保存功能实现为独立于实体,因此我认为最好也使测试独立于实体。目前我的 jmockit tests that is autowired with spring.
之一有以下内容
@Injectable
public EntityManager em;
@Tested
SyncClaimDao syncClaimDao = new SyncClaimDaoImpl();
@Before
public void setUp() {
Deencapsulation.setField(syncClaimDao, "em", em);
}
private void testSaveEntity (Class T) {
// Existing claim happy path
new Expectations() {
{
em.contains(any); result = true;
em.merge(any);
}
};
if (T.isInstance(SyncClaimEntity.class)) {
Assert.assertTrue(syncClaimDao.saveClaim(new SyncClaimEntity()));
} else if (...) {...}
}
@Test
public void testSaveClaim() {
testSaveEntity(SyncClaimEntity.class);
}
SyncClaimDaoImpl
@Override
public boolean saveClaim(SyncClaimEntity claim) {
return saveEntity(claim);
}
private boolean saveEntity(Object entity) {
boolean isPersisted = false;
try {
isPersisted = em.contains(entity);
if (isPersisted) {
em.merge(entity);
} else {
em.persist(entity);
em.flush();
isPersisted = true;
}
logger.debug("Persisting " + entity.getClass().getSimpleName() + ": " + entity.toString());
}
catch (NullPointerException ex) {
...
}
catch (IllegalArgumentException ex) {
...
}
return isPersisted;
}
当我 运行 测试时,我看到以下错误:
mockit.internal.MissingInvocation: Missing invocation of:
javax.persistence.EntityManager#contains(Object)
with arguments: any Object
on mock instance: javax.persistence.$Impl_EntityManager@44022631
at at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
... 4 more
Caused by: Missing invocation
at [redacted].dal.dao.SyncClaimDaoImplTest.<init>(SyncClaimDaoImplTest.java:48)
at [redacted].dal.dao.SyncClaimDaoImplTest.testSaveEntity(SyncClaimDaoImplTest.java:46)
at [redacted].dal.dao.SyncClaimDaoImplTest.testSaveClaim(SyncClaimDaoImplTest.java:67)
... 10 more
现在,如果我像这样将 Expectations 块移动到 @Test 方法中:
@Test
public void testSaveClaim() {
new Expectations() {
{
em.contains(any); result = true;
em.merge(any);
}
};
Assert.assertTrue(syncClaimDao.saveClaim(new SyncClaimEntity()));
我得到了一个成功的测试 运行,这是应该的。我认为测试方法的 spring 自动装配没有正确确定我的期望范围。这就是我看到缺少调用错误的原因。
有没有人知道如何泛化我的期望以便我可以为泛化方法创建更简单的测试?
我现在看到错误了:T.isInstance(SyncClaimEntity.class)
。 Class#isInstance(Object)
方法应该用 class 的一个实例 调用,而不是用 class 本身调用;所以,它总是返回 false 因为 SyncClaimEntity.class
显然不是 SyncClaimEntity
.
的实例
所以我想对几种不同的 Dao 方法使用通用测试。在 Dao 内部,我将保存功能实现为独立于实体,因此我认为最好也使测试独立于实体。目前我的 jmockit tests that is autowired with spring.
之一有以下内容@Injectable
public EntityManager em;
@Tested
SyncClaimDao syncClaimDao = new SyncClaimDaoImpl();
@Before
public void setUp() {
Deencapsulation.setField(syncClaimDao, "em", em);
}
private void testSaveEntity (Class T) {
// Existing claim happy path
new Expectations() {
{
em.contains(any); result = true;
em.merge(any);
}
};
if (T.isInstance(SyncClaimEntity.class)) {
Assert.assertTrue(syncClaimDao.saveClaim(new SyncClaimEntity()));
} else if (...) {...}
}
@Test
public void testSaveClaim() {
testSaveEntity(SyncClaimEntity.class);
}
SyncClaimDaoImpl
@Override
public boolean saveClaim(SyncClaimEntity claim) {
return saveEntity(claim);
}
private boolean saveEntity(Object entity) {
boolean isPersisted = false;
try {
isPersisted = em.contains(entity);
if (isPersisted) {
em.merge(entity);
} else {
em.persist(entity);
em.flush();
isPersisted = true;
}
logger.debug("Persisting " + entity.getClass().getSimpleName() + ": " + entity.toString());
}
catch (NullPointerException ex) {
...
}
catch (IllegalArgumentException ex) {
...
}
return isPersisted;
}
当我 运行 测试时,我看到以下错误:
mockit.internal.MissingInvocation: Missing invocation of:
javax.persistence.EntityManager#contains(Object)
with arguments: any Object
on mock instance: javax.persistence.$Impl_EntityManager@44022631
at at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
... 4 more
Caused by: Missing invocation
at [redacted].dal.dao.SyncClaimDaoImplTest.<init>(SyncClaimDaoImplTest.java:48)
at [redacted].dal.dao.SyncClaimDaoImplTest.testSaveEntity(SyncClaimDaoImplTest.java:46)
at [redacted].dal.dao.SyncClaimDaoImplTest.testSaveClaim(SyncClaimDaoImplTest.java:67)
... 10 more
现在,如果我像这样将 Expectations 块移动到 @Test 方法中:
@Test
public void testSaveClaim() {
new Expectations() {
{
em.contains(any); result = true;
em.merge(any);
}
};
Assert.assertTrue(syncClaimDao.saveClaim(new SyncClaimEntity()));
我得到了一个成功的测试 运行,这是应该的。我认为测试方法的 spring 自动装配没有正确确定我的期望范围。这就是我看到缺少调用错误的原因。
有没有人知道如何泛化我的期望以便我可以为泛化方法创建更简单的测试?
我现在看到错误了:T.isInstance(SyncClaimEntity.class)
。 Class#isInstance(Object)
方法应该用 class 的一个实例 调用,而不是用 class 本身调用;所以,它总是返回 false 因为 SyncClaimEntity.class
显然不是 SyncClaimEntity
.