如何在不考虑数据库活动的情况下编写JUnit测试用例

时间:2018-11-13 04:24:02

标签: java hibernate junit testcase

以下是我的测试班

{
    'F1': 'Value1', 
    'F2': 'Value2',
    'F3': '[[F4=Value4,F5=Value5]]',
    'F6': 'Value6'
}

在服务调用的DAO层 paymentService.setPaidStatusList()中,有一些与数据库活动有关的保存和更新操作,例如@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("/ds-context.xml") @WebAppConfiguration public class PaidListTest { @Autowired PaymentService paymentService; @Test public void getPaidList() { List<PaymentGetServiceDO> response = null; try { response = paymentService.setPaidStatusList(); if(response != null && response.size() > 0){ for(int i = 0; i < response.size(); i++){ assertNotNull(response.get(i).getAgentcode()); } } } catch (Exception e) { e.printStackTrace(); } } }
但是我不想要要在调用测试方法时执行它们,仅在调用实际业务逻辑时才需要调用它们。
如何在此处限制或回滚数据库事务?
服务和DAO方法在这里很乏味。但是,我已经简化了它们以供参考。
服务方法 em.merge(renewalPoliciesDO);
DAO实施

if(!updateList.isEmpty()){
HashMap<String,String> recordset = new HashMap<String,String>();
    recordset = paymentDAO.setRenewalStatus(updateList);
}

就我而言,我需要结果数组列表,但是if(paymentUpdateResDO.getPaymentstatus().equalsIgnoreCase("MANUAL") && !responseUpdateStatus.getPolicystatusid().equals(renewedStatusId)){ CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder(); CriteriaQuery<Integer> payQuery = criteriaBuilder.createQuery(Integer.class); Root<PaymentStatusDO> payRoot = payQuery.from(PaymentStatusDO.class); payQuery.multiselect(payRoot.get("paymentstatusid")); payQuery.where(criteriaBuilder.equal(payRoot.get("paymentstatusdescription"), "Manual")); Integer paymentStatusId = em.createQuery(payQuery).getSingleResult(); insertOldPolicy(responseUpdateStatus); responseUpdateStatus.setNewpolicyno(paymentUpdateResDO.getNewpolicyno()); responseUpdateStatus.setPreviousstatusid(responseUpdateStatus.getPolicystatusid()); responseUpdateStatus.setPolicystatusid(renewedStatusId); Timestamp modifiedDate = new Timestamp(System.currentTimeMillis()); responseUpdateStatus.setModifieddatetime(modifiedDate); responseUpdateStatus.setModifiedby("RPA"); responseUpdateStatus.setPaymentstatusid(paymentStatusId); responseUpdateStatus.setActiveindicator("Y"); em.merge(responseUpdateStatus); successRecords++; } em.merge活动需要忽略。

当我以em.persist作为MockitoJUnitRunner的首选方式运行时,我执行了我的测试用例,但是程序终止了,所以我无法获得结果ArrayLists。

Screenshot for successful execution of testcase
引用此图片 Program terminated, so that nothing got executed

3 个答案:

答案 0 :(得分:2)

您可以使用数据库调用的模拟。您可以使用Jmockit编写测试用例,在其中可以模拟数据库调用,这将阻止数据库中的保存或更新操作。

您可以从http://jmockit.github.io/tutorial/Introduction.html

学习编写jmockit测试用例。

https://winterbe.com/posts/2009/08/18/introducing-jmockit/

答案 1 :(得分:2)

您应按照Pooja Aggarwal的建议采取以下方法。

import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;

    @RunWith(MockitoJUnitRunner.class)
    public class PaidListTest {

        @Mock
        PaymentService paymentService;

        @Before
          public void setUp() {
             MockitoAnnotations.initMocks(this);
             mapperObj = new ObjectMapper();
             List<PaymentGetServiceDO> response = new ArrayList<PaymentGetServiceDO>();
}
        @Test
        public void getPaidList() {
            List<PaymentGetServiceDO> response = null;
            try {
                response = paymentService.setPaidStatusList();          
                if(response != null && response.size() > 0){
                    for(int i = 0; i < response.size(); i++){
                        assertNotNull(response.get(i).getAgentcode());
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

此代码将不会执行您的保存和更新操作。

答案 2 :(得分:1)

就像其他人所说的,您可以:

  • 模拟[System.Management.Automation.PSCustomObject],以便您可以准确定义每次调用它要执行的操作。在这种情况下,您只需返回一个硬编码的[System.Management.Automation.PSObject]响应,您的测试就可以做到这一点。这样做的不利之处在于,在这种情况下,您真的测试PaymentService。您只是在查看硬编码的数据,并对其进行处理。我认为这不是有效的测试。

  • 或者,您可以使用内存数据库实例化List<PaymentGetServiceDO>对象,仅用于测试或模拟DB对象,然后您可以在其中精确定义如何响应每个对象PaymentServicePaymentServicemerge和类似操作。如果save对象不允许这样做,则应重新设计它,以便它接受数据库/连接作为参数,在生产中运行时,该参数将是正常的update注入参数,但是您可以可以在测试时手动实例化。这将是一个适当的测试,因为您将验证PaymentService内的其余逻辑,但实际上并没有达到这个目的。