I’m working with the Struts2 framework and would like to unit test the execute method below:
public String execute() {
setDao((MyDAO) ApplicationInitializer.getApplicationContext().getBean("MyDAO"));
setUserPrincipal(); //fetches attribute from request and stores it in a var
setGroupValue(); //
setResults(getMyDao().getReportResults(getActionValue(), getTabName());
setFirstResultSet((List) getResults()[0]);
setSecondResultSet((List) getResults()[1]);
return SUCCESS;
}
As you can see most of the logic is database related. So how would I go about unit testing this functionality? I would like to unit test by mocking a HTTPServletRequest with few request variables inside it.
My questions are:
- How can I fake/mock a request variable as if its coming from a browser
- Should my unit test be calling the actual DAO and making sure that the data is coming back?
- If so, how can I call the DAO from unit test since the DAO is tied to the server since jndi pool settings reside on the application server.
I’d appreciate any book/article that shows how to really accomplish this.
The code you have shown us is not enough to fully answer your question.
Line by line
This is the hardest line since it uses static method. We would need to see how
ApplicationInitializerworks. In ideal world thegetApplicationContext()method should return mock ofApplicationContext. This mock in turns should returnMyDAOwhengetBean("MyDAO"). mockito is perfectly capable of handling this, as well as all other mocking frameworks.Where does the request come from? Is it injected to action class? If so, simply inject mocked request object, e.g.
MockHttpServletRequest.Same as above? Please provide more details, what this method actually does?
Your previously created mock should return something when
getReportResults()is called with given arguments.I guess methods below set some field on the action class. Because you have full control over what was returned from mocked
getReportResults(), this is not a problem.You can assert whether
SUCCESSwas the result of execution.Now in general
See above, there is a mock built-in in Spring.
If your unit test calls real DAO, it is no longer unit test. It is an integration test.
This means you are doing integration testing. In that case you should use in-memory database like h2 so you can still run the test on ci server. You must somehow configure your application to fetch
DataSourcefrom different place.Final note
In essence you should inject mocks of everything to your Struts action class. You can tell mocks to return any value upon calling. Then, after calling
execute(), you can verify given methods were called, fields set and result value is correct. Consider splitting this to several tests.Code review
MyDAOto your action class. The first line becomes obsolete.