Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
504 views
in Technique[技术] by (71.8m points)

junit - How to use mockito for testing Database connection

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.

EDIT :

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 );
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

You could mock it like

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)

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

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

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>

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...