使用 Mockito 对 DAO 层进行单元测试

Posted

技术标签:

【中文标题】使用 Mockito 对 DAO 层进行单元测试【英文标题】:Unit testing DAO layer with Mockito 【发布时间】:2021-03-15 14:36:48 【问题描述】:

尝试测试我的 DAO 方法:

@Repository
@ComponentScan(basePackages = "com.sebhaw.cms.entity")
public class AuthoritiesDAO extends CommonClass implements IDAO<Authorities>

    public final Logger logger = LoggerFactory.getLogger(AuthoritiesDAO.class);
    
    public EntityManager entityManager;
    
    
    @Autowired
    public AuthoritiesDAO(EntityManager entityManager) 
        this.entityManager = entityManager;
    

    private CommonClass commonClass;
    
    static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");
    
    @Override
    public List<Authorities> getObjects() 
        
        Session currentSession = entityManager.unwrap(Session.class);
        Query<Authorities> theQuery = currentSession.createQuery("from Authorities",Authorities.class);
        List<Authorities> authorities = theQuery.getResultList();
        logger.warn("Query getAuthorities() on table Authorities in day: "+dateTimeFormatter.format(LocalDateTime.now())+" by: "+getPrincipal().toString());
        return authorities;
    
    
    @Override
    public void saveObjects(Authorities t) 
        
        Session currentSession = entityManager.unwrap(Session.class);
        t.setLastModifier(getPrincipal());
        logger.warn("Record saved on table Authorities in day: "+dateTimeFormatter.format(LocalDateTime.now())+", data: "+t.toString()+" by: "+getPrincipal().toString());
        currentSession.saveOrUpdate(t);
    
    
    @Override
    public Authorities getObjects(int theId) 
        Session currentSession = entityManager.unwrap(Session.class);
        Authorities theAuthorities = currentSession.get(Authorities.class, theId);
        logger.warn("Query getAuthorities(int theId) on table Authorities in day: "
        +dateTimeFormatter.format(LocalDateTime.now())+"with ID: "+theId+" by: "+getPrincipal().toString());
        return theAuthorities;
    
    
    @Override
    public void deleteEntities(int theId) 
        
        Session currentSession = entityManager.unwrap(Session.class);
        Query theQuery = currentSession.createQuery("delete from Authorities where id=:authoritiesId");
        theQuery.setParameter("authoritiesId", theId);
        logger.warn("Record deleted in table Authorities on day: "+dateTimeFormatter.format(LocalDateTime.now())+", with ID: "+theId+" by: "+getPrincipal().toString());
        theQuery.executeUpdate();   
    

这是我的单元测试(不工作):

public class AuthoritiesDAOTest 
    
    @Mock
    private Session session;
    
    private EntityManager entityManager;
    
    private CommonClass commonClass;
    
    private AuthoritiesDAO authoritiesDAO;
    
    @BeforeEach
    void init() 
        entityManager = Mockito.mock(EntityManager.class);
        Mockito.when(entityManager.unwrap(Session.class)).thenReturn(session);
        authoritiesDAO = new AuthoritiesDAO(entityManager);
    
    
    @Test
    void shouldReturnEmptyCollection() 
        Query query = Mockito.mock(Query.class);
        Mockito.when(session.createQuery(ArgumentMatchers.anyString(),ArgumentMatchers.any())).thenReturn(query);
        Mockito.when(query.getResultList()).thenReturn(new ArrayList<Authorities>());
        
        List<Authorities> result = authoritiesDAO.getObjects();
        assertTrue(true);
    


由于我处于死胡同,我要求提供对我的 dao 层进行有效单元测试的示例。 “Neque porro quisquam est qui dolorem ipsum quia dolor sit amet、consectetur、adipisci velit……” “Neque porro quisquam est qui dolorem ipsum quia dolor sit amet、consectetur、adipisci velit……” “Neque porro quisquam est qui dolorem ipsum quia dolor sit amet、consectetur、adipisci velit……” "Neque porro quisquam est qui dolorem ipsum quia dolor sit amet、consectetur、adipisci velit..."

【问题讨论】:

“不工作”不是一个有用的描述。请提供错误消息和堆栈跟踪(如果有),或者以其他方式清楚地解释在这种情况下“不工作”的含义(即您遇到的行为以及它与您的预期有何不同)。这样,您就不需要将部分 Lorem Ipsum 附加到您的问题中。嗯,“问题”。就像现在一样,它的措辞非常类似于“给我代码”,您可能也想对其进行编辑。阅读How to Ask 了解一些提示。 我的假的。我在第 46 行有 NullPointerException:Mockito.when(session.createQuery(ArgumentMatchers.anyString(),ArgumentMatchers.any())).thenReturn(query); 将其包含在问题中。 【参考方案1】:

你可以自己google一下,会得到多个链接。部分链接

https://dzone.com/articles/unit-testing-dao-service-and-controller-in-spring
https://howtodoinjava.com/best-practices/how-you-should-unit-test-dao-layer/

【讨论】:

您认为我是在寻求 Google 指南还是以代码的形式寻求帮助,因为我已经用尽了指南中所有可能的选项? “我在找我的 dao 层的有效单元测试示例,因为我处于死胡同。”这是什么意思?

以上是关于使用 Mockito 对 DAO 层进行单元测试的主要内容,如果未能解决你的问题,请参考以下文章

如何在服务层单元测试中模拟数据库结果?

Android 应用测试 - 如何使用真实数据库测试 DAO 层?

使用 H2 数据库对 DAO 层进行单元测试

如何用mockito+spring进行单元测试

2编写单元测试用例,对用户注册功能的DAO层进行测试。(注意:测试用例应考虑成功和失败的情况)

使用 mockito 对插入方法进行单元测试