如何使用Spring自动装配来推广JMockit测试

时间:2015-01-13 00:37:34

标签: jmockit

所以我想对一些不同的Dao方法使用泛型测试。在Dao中,我实现了保存功能是独立于实体的,所以我认为最好使测试实体独立。目前,对于自动装配的测试之一,我有以下内容。

@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$1.<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()));

我应该成功进行测试。我认为测试方法的自动装配不能正确地确定我的期望。这就是我看到缺少调用错误的原因。

有没有人对如何概括我的期望有任何想法,所以我可以为通用方法创建更简单的测试?

1 个答案:

答案 0 :(得分:0)

我现在看到了错误:T.isInstance(SyncClaimEntity.class)。应该使用类的实例来调用Class#isInstance(Object)方法,而不是使用类本身;因此,它始终返回false,因为SyncClaimEntity.class显然不是SyncClaimEntity的实例。