如何使用 mockito 测试数据库连接 [英] How to use mockito for testing Database connection

查看:113
本文介绍了如何使用 mockito 测试数据库连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Junit 来测试我的球衣 api.我想在没有数据库的情况下测试 DAO.我尝试使用 Mockito,但仍然无法使用模拟对象来测试包含对 DB 的 Hibernate 调用的 DAO.我想为调用 DAO 的 Helper 类编写 Junit.谁能提供带有一些示例代码的解决方案来模拟 DAO 中的数据库连接.

I am using Junit to test my jersey api. I want to test DAO without a database. I tried using Mockito but still not able to use mock object to test the DAO which contains Hibernate calls to DB. I want to write Junit for my Helper class which calls the DAO.Can anyone provide a solution with some sample code to mock the DB Connections in DAO.

Status.java

@GET
@Produces(MediaType.TEXT_PLAIN)
public String getDBValue() throws SQLException {
    DatabaseConnectionDAO dbConnectiondao = new DatabaseConnectionDAO();
    String dbValue = dbConnectiondao.dbConnection();
    return dbValue;
}

DatabaseConnectionDAO.java

private Connection con;
private Statement stmt;
private ResultSet rs;
private String username;

public String dbConnection() throws SQLException{
    try{
        Class.forName("com.mysql.jdbc.Driver");
        con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "root", "root");
        stmt = con.createStatement();
        rs =stmt.executeQuery("select * from test");

        while(rs.next()){
            username = rs.getString(1);             
        }           
    }catch(Exception e){
        e.printStackTrace();            
    }finally{
    con.close();    
    }
    return username;
}

TestDatabase.java

@Test
public void testMockDB() throws SQLException{
    DatabaseConnectionDAO mockdbDAO = mock(DatabaseConnectionDAO.class);
    Connection con = mock(Connection.class);
    Statement stmt = mock(Statement.class);
    ResultSet rs = mock(ResultSet.class);

    Client client = Client.create();
    WebResource webResource = client.resource("myurl");
    ClientResponse response = webResource.accept(MediaType.TEXT_PLAIN).get(ClientResponse.class);

    verify(mockdbDAO).dbConnection();

    //when(rs.next()).thenReturn(true);
    when(rs.getString(1)).thenReturn(value);    

    actualResult = response.getEntity(String.class);
    assertEquals(expectedResult,actualResult );
}

推荐答案

我认为您可能没有想到应该如何模拟 DAO.您不必担心任何连接.通常,您只想模拟在调用其方法时会发生什么,例如 findXxx 方法.例如,假设您有这个 DAO 接口

I think you may be missing the idea of how the DAO should be mocked. You shouldn't have to worry about any connections. Generally, you just want to mock what happens, when its methods are called, say a findXxx method. For instance, say you have this DAO interface

public interface CustomerDAO {
    public Customer findCustomerById(long id);
}

你可以模仿它

CustomerDAO customerDao = Mockito.mock(CustomerDAO.class);

Mockito.when(customerDao.findCustomerById(Mockito.anyLong()))
        .thenReturn(new Customer(1, "stackoverflow"));

然后您将不得不注入"那个模拟实例到依赖它的类中.例如,如果一个资源类需要它,你可以通过构造函数注入它

You would then have to "inject" that mocked instance into the class that depends on it. For example, if a resource class needs it, you could inject it via the constructor

@Path("/customers")
public class CustomerResource {
    
    CustomerDAO customerDao;
    
    public CustomerResource() {}
    
    public CustomerResource(CustomerDAO customerDao) {
        this.customerDao = customerDao;
    }
    
    @GET
    @Path("/{id}")
    @Produces(MediaType.APPLICATION_JSON)
    public Response findCustomer(@PathParam("id") long id) {
        Customer customer = customerDao.findCustomerById(id);
        if (customer == null) {
            throw new WebApplicationException(Response.Status.NOT_FOUND);
        }
        return Response.ok(customer).build();
    }
}

...

new CustomerResource(customerDao)

不,当您点击 findCustomer 方法时,DAO 将始终返回模拟 DAO 中的 Customer.

No when you hit the findCustomer method, the DAO will always return the Customer in the mocked DAO.

这是一个完整的测试,使用 Jersey 测试框架

Here's a complete test, using the Jersey Test Framework

public class CustomerResourceTest extends JerseyTest {

    private static final String RESOURCE_PKG = "jersey1.stackoverflow.standalone.resource";
    
    public static class AppResourceConfig extends PackagesResourceConfig {

        public AppResourceConfig() {
            super(RESOURCE_PKG);
            
            CustomerDAO customerDao = Mockito.mock(CustomerDAO.class);
            Mockito.when(customerDao.findCustomerById(Mockito.anyLong()))
                    .thenReturn(new Customer(1, "stackoverflow"));
           
            getSingletons().add(new CustomerResource(customerDao));
        }

    }

    @Override
    public WebAppDescriptor configure() {
        return new WebAppDescriptor.Builder()
                .initParam(WebComponent.RESOURCE_CONFIG_CLASS,
                        AppResourceConfig.class.getName()).build();
    }

    @Override
    public TestContainerFactory getTestContainerFactory() {
        return new GrizzlyWebTestContainerFactory();
    }
    
    @Test
    public void testMockedDAO() {
        WebResource resource = resource().path("customers").path("1");
        String json = resource.get(String.class);
        System.out.println(json);
    }
}

Customer 类是一个简单的 POJO,具有 long idString name.Jersey 测试框架的依赖项是

The Customer class is simple a POJO with a long id, and String name. The dependency for The Jersey Test Framework is

<dependency>
    <groupId>com.sun.jersey.jersey-test-framework</groupId>
    <artifactId>jersey-test-framework-grizzly2</artifactId>
    <version>1.19</version>
    <scope>test</scope>
</dependency>


更新

上面的示例使用 Jersey 1,因为我看到 OP 使用 Jersey 1.有关使用 Jersey 2(带有注解注入)的完整示例,请参阅 这篇文章

这篇关于如何使用 mockito 测试数据库连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆