How to use mockito for testing Database connection

不羁岁月 提交于 2019-11-28 10:23:06
Paul Samsotha

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

Short answer just don't !

The code that need to be unit tested is the client of the DAO, hence what need to be mocked are the DAOs. DAOs are the component that will integrate the app with an external system (here a database) so they have to be tested as integration tests (i.e. with a real database).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!