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

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

问题描述

我正在使用Junit测试我的球衣api.我想在没有数据库的情况下测试DAO.我尝试使用Mockito,但仍然无法使用模拟对象来测试包含对数据库的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返回客户.

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类是带有long idString name的简单POJO. 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使用的是Jersey1.有关使用Jersey 2(带有注解注入)的完整示例,请参见


UPDATE

The above example uses Jersey 1, as I saw that the OP is using Jersey 1. For a complete example using Jersey 2 (with annotation injection), see this post

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

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