How to test DAO with DataSource in Java Web Application?

五迷三道 提交于 2019-12-12 05:25:52

问题


I'm doing my project using Tomcat 7, JSP, Servlets, Log4j and MySQL.

I've googled this question for hours with no proper answer.

How can I test my DAO's using DataSource and JUnit ?

I found this article recently, but don't know how to configure it for my purposes and don't sure if it's a good way of doing it.

I'm having the following DAO hierarchy:

And I'm obtaining the DataSource in AbstractRepository in the following way:

...
protected final DataSource ds;
...
    public AbstractRepository() {
        DataSource dataSource = null;
        try {
            Context initContext = new InitialContext();
            dataSource = (DataSource) initContext
                    .lookup("java:/comp/env/jdbc/mydb");
        } catch (NamingException ex) {
            LOG.error("Cannot obtain a connection from the pool", ex);
        }
        ds = dataSource;
    }
...

Would you produce some code sample of the way to solve this problem for example for Entrant Repository Test?


回答1:


The code you have in AbstractRepository is pretty hard to test. The reason is the "smart constructor", that knows where he gets the datasource from. But you still have a number of options. You can either change your code (my choice) so that the constructor receives DataSource as a parameter, like

public AbstractRepository(DataSource dataSource){
  this.ds = dataSource;
}

so you will be able to initialize your repositories in Test environment with some test datasource (a mock?).

Or you can use some mocking Framework, e.g. EasyMock, to create a partial mock of the Repository you want to test. EasyMock creates partial mocks of classes without calling any constructor by default. Then you could either mock the getDataSource() method (I hope you have one, that is used everywhere you need to access the datasource?) to return the test datasource, or you can set the final ds field using Reflections (the worse choice, I suppose).




回答2:


The problem is that your code gets its dependency directly from the source. The advice I provided your previous question is similar to the advice from Alexey Gromov, but if for some reason you cannot change your code then you would need to do the following in your unit test:

1) Create the sub contexts that would be created for you normally using your Java container (e.g. Tomcat, Jetty). THat can be done using the following commands which I got from your link (i verified they work):

    System.setProperty(Context.INITIAL_CONTEXT_FACTORY,
            "org.apache.naming.java.javaURLContextFactory");
        System.setProperty(Context.URL_PKG_PREFIXES, 
            "org.apache.naming");  

    Context ic = new InitialContext();
    ic.createSubcontext("java:");
    ic.createSubcontext("java:/comp");
    ic.createSubcontext("java:/comp/env");
    ic.createSubcontext("java:/comp/env/jdbc");

2) You need to bind your mock object to the name that your code is expecting. That can be done using InitialContext#bind.

ic.bind("java:/comp/env/jdbc/DSTest", mock(DataSource.class)); 

Please note that mock function is provided by Mockito... you can pass what ever mock object you want.

In my actual code I have this:

        mysqlDs = (DataSource) initCtx.lookup("java:/comp/env/jdbc/DSTest");
        System.out.println("----mysqlDs = " + mysqlDs + "\n");

Which prints out:

----mysqlDs = Mock for DataSource, hashCode: 1926808117



回答3:


With TomcatJNDI you can easily access the Tomcat JNDI environment from within your classes as when your application would run within Tomcat. TomcatJNDI leverages Tomcat's JNDI system and configures it by processing the original Tomcat configuration files. It's usage is simple, e. g.

TomcatJNDI tomcatJNDI = new TomcatJNDI();
tomcatJNDI.processContextXml(contextXmlFile);
tomcatJNDI.processWebXml(webXmlFile);
tomcatJNDI.start();

Thereafter you can lookup the DataSource as you are used to. More information can be found here.



来源:https://stackoverflow.com/questions/28381396/how-to-test-dao-with-datasource-in-java-web-application

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