繁体   English   中英

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

[英]How to write JUnit test cases with ignoring database activities

以下是我的测试课

@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层中, paymentService.setPaidStatusList()具有一些保存和更新数据库活动的操作,例如em.merge(renewalPoliciesDO);
但是我不想在调用测试方法时执行它们,仅在调用实际业务逻辑时才需要调用它们。
如何在此处限制或回滚数据库事务?
服务和DAO方法在这里很乏味。 但是,我已经简化了它们以供您参考。
服务方法 if(!updateList.isEmpty()){ HashMap<String,String> recordset = new HashMap<String,String>(); recordset = paymentDAO.setRenewalStatus(updateList); } if(!updateList.isEmpty()){ HashMap<String,String> recordset = new HashMap<String,String>(); recordset = paymentDAO.setRenewalStatus(updateList); }
DAO实施

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 ,但是em.mergeem.persist活动需要忽略。

当我尝试使用MockitoJUnitRunner @GauravRai1512 ,我执行了我的测试用例,但是程序终止了,因此无法获得结果ArrayLists。

成功执行测试用例的屏幕截图
参照这张图片 程序终止,所以什么也没有执行

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

您可以从http://jmockit.github.io/tutorial/Introduction.html学习编写jmockit测试用例

要么

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

您应遵循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();
            }
        }
    }

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

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

  • 模拟PaymentService以便您可以精确定义每次调用它所要执行的操作。 在这种情况下,您只需返回一个硬编码的List<PaymentGetServiceDO>响应,您的测试就可以做到这一点。 不利的PaymentService是,您在这种情况下并没有真正测试PaymentService 您只是在查看硬编码的数据,并对其进行处理。 我认为这不是有效的测试。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM