java - 使用 mockito 测试 Hibernate DAO 方法
问题描述
我访问了很多博客和网站,以了解如何使用 Mockito 在 Hibernate 中测试我的 DAO 方法,但我还没有找到任何可以帮助我编写代码的具体示例。我发现我必须使用集成测试而不是 JUnit 测试,但我真的不知道如何用我的代码来做到这一点。
问题:如何尽可能好地测试我的 DAO 方法?
我的代码:
我的测试只使用了 mockito 部分:
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class UserDAOTest
{
@Mock
private UserDAO userDAO;
@Before
public void setUp()
{
MockitoAnnotations.initMocks(this);
}
@Test
public void testAddUser_AddsNewUser()
{
}
@Test
public void testDeleteUser_DeletesUser()
{
}
@Test
public void testGetUser_FetchUser()
{
}
@Test
public void testGetUsers_FetchesAllUsers()
{
}
}
我的用户道:
import Hibernate.HibernateUtil;
import Hibernate.Models.User;
import org.hibernate.HibernateException;
import org.springframework.stereotype.Repository;
import org.hibernate.Session;
import org.hibernate.Transaction;
import java.util.List;
//@Transactional
@Repository
public class UserDAO extends GeneralDAO
{
public void addUser(User user)
{
add(user);
}
/**
* Deletes a user from the database based on the userID
* @param userID
*/
public void deleteUser(int userID)
{
User user = new User();
delete(userID, user);
}
public User getUser(int userID) throws Exception
{
Transaction transaction = null;
User user = null;
try (Session session = HibernateUtil.getSessionFactory().openSession())
{
// start a transaction
transaction = session.beginTransaction();
// Gets the user object
user = session.get(User.class, userID);
// commit transaction
transaction.commit();
//closing session
session.close();
return user;
} catch (Exception e) {
if (transaction != null) {
transaction.rollback();
}
e.printStackTrace();
return user;
}
}
public List<User> getUsers() throws HibernateException, Exception
{
try(Session session = HibernateUtil.getSessionFactory().openSession()){
return session.createQuery("FROM User", User.class).getResultList();
}
}
}
我的GeneralDAO:
import Hibernate.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.springframework.stereotype.Repository;
//@Transactional
@Repository
public class GeneralDAO
{
public void add(Object obj)
{
Transaction transaction = null;
try (Session session = HibernateUtil.getSessionFactory().openSession())
{
// start a transaction
transaction = session.beginTransaction();
// add the user object
session.save(obj);
// commit transaction
transaction.commit();
//closing session
session.close();
} catch (Exception e)
{
if (transaction != null)
{
transaction.rollback();
}
e.printStackTrace();
}
}
public void delete(int userID, Object obj)
{
Transaction transaction = null;
try (Session session = HibernateUtil.getSessionFactory().openSession())
{
obj = session.load(obj.getClass(), userID);
// start a transaction
transaction = session.beginTransaction();
//deleting the user from the db
session.delete(obj);
// commit transaction
transaction.commit();
//closing session
session.close();
} catch (Exception e)
{
if (transaction != null)
{
transaction.rollback();
}
e.printStackTrace();
}
}
}
解决方案
您阅读的有关测试 DAO 的内容是正确的方法。
不要使用 Mockito 测试 DAO/存储库层。
您不想编写一个断言确实调用了语句流的单元测试:
// start a transaction
transaction = session.beginTransaction();
// add the user object
session.save(obj);
// commit transaction
transaction.commit();
//closing session
session.close();
编写这种测试意味着主要编写模拟来描述流程。
没有价值,因为它在逻辑/行为方面没有任何检查。
同样,断言查询是无用的。您可以在 DAO 中编写“SELECT SELECT SELECT”作为查询,如果您依赖检查查询文本,您的测试仍然可以成功。
你使用弹簧。如果你也使用 Spring Boot,你应该依赖于@DataJpaTest
专注于测试数据访问组件的测试切片。
否则,别担心。我们在 Spring Boot 之前就做到了。所以我们还是可以做到的。
为您的测试配置一个内存数据库(例如 H2),并根据测试方法清除/填充数据。
例如 :
@Autowired
UserDAO userDAO;
@Test
public void getUser_retrieves_users_added_by_addUser(){
User addedUser = userDAO.add(new User("foo", "bar"));
// ... flush data in the database and clear first cache level to avoid cache using
User expectedUser = userDAO.get(addedUser.getId());
// assert the expected User
}
@Before
public void tearDown(){
// clear data in the database
}
推荐阅读
- express - 命令性地运行 oneOf 验证?
- python - Amazon Lex 回退功能到 Amazon Alexa 或 Google 协助
- r - 有没有办法在单个日期时间列中查找时差,按 ID 分组?
- django - get_absolute_url 创建空白链接
- node.js - 某些应用程序的 pm2 计划重新加载
- java - 使用 Java 流从员工列表中获取特定日期之前和之后的员工
- python-3.x - 从 many2many 向导(或)TransientModel 在 Many2one 字段中创建值
- php - PHP Curl 发布并获得响应
- c++ - 带有自定义重采样变换过滤器的 Directshow
- python - Python 中的函数将列表视为全局变量。如何解决这个问题?