简体   繁体   English

使用 mockito 测试 Hibernate DAO 方法

[英]Testing Hibernate DAO methods with mockito

I have visited a lot of blogs and websites to learn how I can test my DAO methods in Hibernate with Mockito, but I haven't found any specific example that could help me with my code.我访问了很多博客和网站,以了解如何使用 Mockito 在 Hibernate 中测试我的 DAO 方法,但我还没有找到任何可以帮助我编写代码的具体示例。 All I have found is that I have to use Integration test instead of JUnit test but I don't really know how to do that with my code.我发现我必须使用集成测试而不是 JUnit 测试,但我真的不知道如何用我的代码来做到这一点。

QUESTION: How can I test my DAO methods as good as possible?问题:我怎样才能尽可能好地测试我的 DAO 方法?

MY CODE:我的代码:

My test with only the mockito part:我只使用模拟部分的测试:

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()
{

}
}

My UserDAO:我的 UserDAO:

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();
    }

}
}

My GeneralDAO:我的 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();
    }
}
}

What you read about testing DAO is the correct way.你读到的关于测试 DAO 的内容是正确的。
Don' test with Mockito the DAO/repository layer.不要使用 Mockito 测试 DAO/存储库层。

You don't want to write an unit test that asserts that a flow of statements was indeed invoked :您不想编写断言确实调用了语句流的单元测试:

// start a transaction
transaction = session.beginTransaction();

// add the user object
session.save(obj);

// commit transaction
transaction.commit();

//closing session
session.close();

Writing this kind of test means writing mainly mock to describe the flow.写这种测试,主要是写mock来描述流程。
No value because it checks nothings in terms of logical/behavior.没有价值,因为它在逻辑/行为方面没有检查任何东西。
Similarly, asserting a query is useless.同样,断言查询也是无用的。 You could write "SELECT SELECT SELECT" as query in your DAO and your test could still success if you rely on checking query text.您可以在 DAO 中编写“SELECT SELECT SELECT”作为查询,如果您依靠检查查询文本,您的测试仍然可以成功。

You use Spring.你使用弹簧。 If you also use Spring Boot, you should rely on the @DataJpaTest test slicing that focuses on testing the data access components.如果您还使用 Spring Boot,则应该依赖于专注于测试数据访问组件的@DataJpaTest测试切片。
Otherwise, don't worry.否则,别担心。 We did it before Spring Boot.我们在 Spring Boot 之前做到了。 So we could still do it.所以我们仍然可以做到。
Configure an in memory database (H2 for example) for your test, and clear/populate data according to the tested method.为您的测试配置内存数据库(例如 H2),并根据测试方法清除/填充数据。
For example :例如 :

@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
}

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

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