Testing spring mvc controller having the view with tiles configuration - spring

I dont know how to test a controller that has view with tiles configuration.
Below is the unit test case written
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import junit.framework.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.context.ApplicationContext;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.ModelAndView;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations={"file:src/main/webapp/WEB-INF/servlet-context.xml", "file:src/main/webapp/WEB-INF/tiles-definitions.xml"})
#TestExecutionListeners(DependencyInjectionTestExecutionListener.class)
public class BankControllerTest {
#Inject
private ApplicationContext applicationContext;
private HandlerAdapter handlerAdapter;
private MockHttpServletRequest request;
private MockHttpServletResponse response;
private BankController controller;
private ModelAndView handle(final HttpServletRequest request, final HttpServletResponse response) throws Exception {
final HandlerMapping handlerMapping = applicationContext.getBean(HandlerMapping.class);
final HandlerExecutionChain handler = handlerMapping.getHandler(request);
Assert.assertNotNull("No handler found for request, check you request mapping", handler);
final Object controller = handler.getHandler();
for (final HandlerInterceptor interceptor : handlerMapping.getHandler(request).getInterceptors()) {
if (!interceptor.preHandle(request, response, controller)) {
return null;
}
}
return handlerAdapter.handle(request, response, controller);
}
#Before
public void setUp() throws Exception {
request = new MockHttpServletRequest();
response = new MockHttpServletResponse();
this.handlerAdapter = applicationContext.getBean(HandlerAdapter.class);
}
#Test
public void banksList() throws Exception {
request.setRequestURI("/banksList.do");
request.setMethod("GET");
final ModelAndView mav = handle(request, response);
// assertViewName(mav, "banksList");
// assertAndReturnModelAttributeOfType(mav, "banksList",
// BankList.class);
}
}
I get the following error
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from URL [file:src/main/webapp/WEB-INF/sach-context.xml]
INFO : org.springframework.context.annotation.ClassPathBeanDefinitionScanner - JSR-330 'javax.inject.Named' annotation found and supported for component scanning
INFO : org.springframework.context.annotation.ClassPathBeanDefinitionScanner - JSR-330 'javax.inject.Named' annotation found and supported for component scanning
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from URL [file:src/main/webapp/WEB-INF/tiles-definitions.xml]
ERROR: org.springframework.test.context.TestContextManager - Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener#2c1e6b] to prepare test instance [com.myapp.simulator.controller.BankControllerTest#811c88]
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:308)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:321)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from URL [file:src/main/webapp/WEB-INF/tiles-definitions.xml]; nested exception is java.net.UnknownHostException: tiles.apache.org
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:408)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:334)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:143)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:178)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:149)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:212)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:81)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:1)
at org.springframework.test.context.TestContext.loadApplicationContext(TestContext.java:280)
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:304)
... 24 more
Caused by: java.net.UnknownHostException: tiles.apache.org
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at sun.net.NetworkClient.doConnect(Unknown Source)
at sun.net.www.http.HttpClient.openServer(Unknown Source)
at sun.net.www.http.HttpClient.openServer(Unknown Source)
at sun.net.www.http.HttpClient.<init>(Unknown Source)
at sun.net.www.http.HttpClient.New(Unknown Source)
at sun.net.www.http.HttpClient.New(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.connect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startDTDEntity(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.setInputSource(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.dispatch(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source)
at org.springframework.beans.factory.xml.DefaultDocumentLoader.loadDocument(DefaultDocumentLoader.java:75)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:388)
... 34 more
How to overcome this error. What is the testing approach for controller. do i need to use any other framework in order to write testcases for my controllers

Put the lazy-init="true" for tiles bean configuration as below.
class="org.springframework.web.servlet.view.tiles2.TilesConfigurer" lazy-init="true"

It depends on what you want to test. If you are just making sure that the tile view names are correct, then it is correct you don't have to use Spring Configuration. However if you want to see if a view is resolved or check model attributes, responses, etc then Spring has a MVC testing framework. It was a standalone, but it is now part of 3.2. So if you are using Spring 3 you might want to look at the tests in SpringMVC Showcase. I haven't tested it yet with Tiles, but it does have the ability to set a view resolver so it should be possible.

The problem is that you can not load a spring context with beans that requires an web container.
If you only want to test the controllers, then I recommend real Unit test, without Spring Context. That mean you need to create mocks for the classes that are required by your controller.

I am using the following to load test cases in spring boot with tiles as an example
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = {MyApplication.class, TestConfigurtaion.class})
#WebAppConfiguration
public class UserRepositoryTest {
#Autowired
UserRepository userRepository;
#Test
public void testCase{
}
}
Then another class for tiles configuration
#Configuration
public class TestConfigurtaion {
#Bean
public TilesConfigurer tilesConfigurer() {
TilesConfigurer configurer = new TilesConfigurer();
configurer.setDefinitions(new String[] { "file:src/main/webapp/WEB-INF/views/tiles.xml" });
configurer.setCheckRefresh(true);
return configurer;
}
}

Related

Spring Boot 2.0.0.M4 throws ConverterNotFoundException on Spring Data REST call

I tried to bump my project up to the most recent Spring Boot 2.0.0 milestone (M4 at the moment of this writing) and I keep getting an exception for a missing Converter (ZonedDateTime to java.util.Date) although it's clearly configured - to me at least. Here's the code and stacktrace:
import org.springframework.core.convert.converter.Converter;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import java.time.ZonedDateTime;
import java.util.Date;
#Component
public class ZonedDateTimePersistenceConverter implements Converter<ZonedDateTime, Date> {
#Nullable
#Override
public Date convert(ZonedDateTime source) {
return Date.from(java.time.ZonedDateTime.now().toInstant());
}
}
When calling the respective Spring Data REST endpoint I get:
2017-09-17 21:07:53.634 ERROR 1894 --- [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.time.ZonedDateTime] to type [java.util.Date]] with root cause
org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.time.ZonedDateTime] to type [java.util.Date]
at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:321) ~[spring-core-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:194) ~[spring-core-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:174) ~[spring-core-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.data.rest.webmvc.HttpHeadersPreparer.lambda$getLastModifiedInMilliseconds$5(HttpHeadersPreparer.java:123) ~[spring-data-rest-webmvc-3.0.0.RC3.jar:na]
at java.util.Optional.map(Optional.java:215) ~[na:1.8.0_131]
at org.springframework.data.rest.webmvc.HttpHeadersPreparer.getLastModifiedInMilliseconds(HttpHeadersPreparer.java:123) ~[spring-data-rest-webmvc-3.0.0.RC3.jar:na]
at org.springframework.data.rest.webmvc.HttpHeadersPreparer.prepareHeaders(HttpHeadersPreparer.java:83) ~[spring-data-rest-webmvc-3.0.0.RC3.jar:na]
at org.springframework.data.rest.webmvc.ResourceStatus.getStatusAndHeaders(ResourceStatus.java:71) ~[spring-data-rest-webmvc-3.0.0.RC3.jar:na]
at org.springframework.data.rest.webmvc.RepositoryEntityController.lambda$getItemResource$3(RepositoryEntityController.java:337) ~[spring-data-rest-webmvc-3.0.0.RC3.jar:na]
at java.util.Optional.map(Optional.java:215) ~[na:1.8.0_131]
at org.springframework.data.rest.webmvc.RepositoryEntityController.getItemResource(RepositoryEntityController.java:333) ~[spring-data-rest-webmvc-3.0.0.RC3.jar:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_131]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_131]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_131]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_131]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209) ~[spring-web-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) ~[spring-web-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) ~[spring-webmvc-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:869) ~[spring-webmvc-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:775) ~[spring-webmvc-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:981) ~[spring-webmvc-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:915) ~[spring-webmvc-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:978) ~[spring-webmvc-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:870) ~[spring-webmvc-5.0.0.RC4.jar:5.0.0.RC4]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:855) ~[spring-webmvc-5.0.0.RC4.jar:5.0.0.RC4]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
...
I've already done some research like debugging and inspecting the GenericConversionService, DefaultConversionService, manually adding it to the converter registry via WebMvcConfigurerAdapter... to no avail.
Any idea where I should look further or what's going here?
Thanks a lot in advance! :)
Edit 1: Additional information to what I've tried and where it's happening. Adding the converter manually didn't help, like so:
#Component
public class AdditionalConverterConfig extends WebMvcConfigurerAdapter {
#Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new ZonedDateTimePersistenceConverter());
}
}
Funnily, the error occurs when I try to access the URI to one of the entities exposed via a Spring Data REST repository (entity is called "Posting", btw), like so:
#RepositoryRestResource(collectionResourceRel = "postings", path = "postings")
public interface PostingRepository extends PagingAndSortingRepository<Posting, Long> {
}
A GET for /api/postings works just fine, listing the first collection page as expected. GET /api/postings/1 however does not. The only critical ZonedDateTime properties in the entity are from its mapped superclass:
#CreatedDate
protected ZonedDateTime createdAt;
#LastModifiedDate
protected ZonedDateTime modifiedAt;
In the listing they appear just fine - in the detail view... not so much ;)

JUnit for Spring including creation of datasource

I am facing an issue with junit. I am trying to autowire Datasource in my junit, but while loading context file it is throwing an error stating failed to load Application context. Please find attached files which contains error trace and junit code. Please let me know if you can help me in this.
The issue is with the xml file entries. It would be helpful if anyone could provide sample codes.
Error Message
-----------------------------------------------------------------------
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:99)
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:122)
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:105)
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:74)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:312)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:284)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
**Caused by: org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 12 in XML document from class path resource [spring-config.xml] is invalid; nested exception is org.xml.sax.SAXParseException; lineNumber: 12; columnNumber: 10; Element type "bean" must be followed by either attribute specifications, ">" or "/>".**
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:396)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:334)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:174)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:209)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:180)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:243)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadBeanDefinitions(AbstractGenericContextLoader.java:233)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:117)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:100)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:248)
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContextInternal(CacheAwareContextLoaderDelegate.java:64)
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:91)
... 25 more
Caused by: org.xml.sax.SAXParseException; lineNumber: 12; columnNumber: 10; Element type "bean" must be followed by either attribute specifications, ">" or "/>".
at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
at org.apache.xerces.util.ErrorHandlerWrapper.fatalError(Unknown Source)
at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
at org.apache.xerces.impl.XMLScanner.reportFatalError(Unknown Source)
at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.DOMParser.parse(Unknown Source)
at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source)
at org.springframework.beans.factory.xml.DefaultDocumentLoader.loadDocument(DefaultDocumentLoader.java:75)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:388)
... 38 more
XML Code
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<context:component-scan base-package="com.jbhunt.apps"/>
    <bean id="testDataSource" class="com.jbhunt.apps.freightmanager.test">
        <property name="testDataSource" ref="dataSource" />
    </bean>
    <bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.ibm.db2.jcc.DB2Driver" />
        <property name="url" value="jdbc:db2://DEVPJES2.jbhunt.com:5031/JBHDB2T" />
        <property name="username" value="rcon666" />
        <property name="password" value="jb8829" />
    </bean>
    <context:property-placeholder location="jdbc.properties" />
Junit Class code
package com.jbhunt.apps.freightmanager.test;
import static org.junit.Assert.assertEquals;
import java.util.List;
import javax.sql.DataSource;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.jbhunt.biz.touring.preplan.dao.DriverOptimizedQuery;
import com.jbhunt.biz.touring.preplan.util.WsOptLdRslHelper;
//#ComponentScan(basePackages = {"com.jbhunt.apps.freightmanager.test"})
#Configuration
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration("/spring-config.xml")
public class DriverViewCursorQueryTest extends JdbcDaoSupport {
#Autowired
private DataSource testDataSource;
#Autowired
public void settestDataSource(#Qualifier ("testDataSource") DataSource testDataSource) {
this.testDataSource = testDataSource;
}
/*#Autowired
public DriverViewCursorQueryTest(#Qualifier ("testDataSource") DataSource dataSource) {
this.setDataSource(dataSource);
}*/
#Before
public void setUp() throws Exception {
}
#Test
public void testGetDriverOptiQuery()
{
List records = null;
String driverAlphaCode = "ALBM0";
try
{
DriverOptimizedQuery drvOptiQry = new DriverOptimizedQuery(testDataSource);
records = (List) drvOptiQry.execute(new Object[] {driverAlphaCode});
}
catch(Exception e)
{
e.printStackTrace();
}
List Actual = WsOptLdRslHelper.getDriverOptimizedQuery(driverAlphaCode);
assertEquals("Objects are equal , Test Successful",records,Actual);
}
}
Looks like the class name is missing (you only have a package name there):
<bean id="testDataSource" class="com.jbhunt.apps.freightmanager.test">
This does not explain the exception you are facing, which is complaining about wrong xml. The xml looks ok at the position lineNumber: 12; columnNumber: 10 . But may be the xml you posted is not the one used by spring ?
Search the whole project for files with name spring-config.xml, may be you have more than one ?
You can also set a breakpoint at DefaultDocumentLoader.java:75, than you can see, which resource is actually used by spring.

Application Context not loaded while running JUnit in a Spring Boot Web Application

I am trying to build a simple web application with Spring Boot 1.3.5 using Java 1.8.
Though the application works alright. But I am having trouble getting my JUnits to run. Have tried finding solution for this, but most of the answers I saw was mainly for Integration testing which I do not want to do. I need simple JUnit test on my methods in my service layer with some mocking. But I don't seem to get it right. JUnits fail with below error. Any help or direction is greatly appreciated.
Failed to load ApplicationContext
java.lang.IllegalStateException: Failed to load ApplicationContext
My JUnit Class is as below where right now I am just checking if the objects are created or not
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = Application.class)
public class ScheduledServiceImplTest{
#Autowired
private ScheduledService scheduledService;
#Mock
private MyDAO mockMyDAO;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
#Test
public void testMockCreation(){
assertNotNull(mockMyDAO);
assertNotNull(scheduledService);
}
}
My Application.java is as below:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.web.SpringBootServletInitializer;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.WebApplicationInitializer;
#SpringBootApplication
#EnableScheduling
public class Application extends SpringBootServletInitializer implements WebApplicationInitializer {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Full stacktrace below:
Failed to load ApplicationContext
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:228)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:230)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:249)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:193)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:86)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:49)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:64)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.messaging.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:106)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.messaging.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:360)
at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:64)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'defaultServletHandlerMapping' defined in class path resource [org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.HandlerMapping]: Factory method 'defaultServletHandlerMapping' threw exception; nested exception is java.lang.IllegalArgumentException: A ServletContext is required to configure default servlet handling

Testing Spring Security and MvcMock using a custom UserDetails implementation

I'm trying to follow this article [1] to mock security in my Spring MvcMock test.
The REST service I want to test looks like this:
#RequestMapping(value = "/something/{id}", method = RequestMethod.DELETE)
public ResponseEntity<Void> deleteXXX(#ActiveUser AppUser user, #PathVariable(value = "id") Long id) {
...
}
where #ActiveUser is a custom implementation/extension of #AuthenticationPrincipal and AppUser is the custom UserDetails implementation.
In the test I do this:
mockMvc.perform(delete("/something/{i}", "123").with(user(new AppUser(...))));
I also added some TestExecutionLIsteners:
#TestExecutionListeners(listeners = { ServletTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class, TransactionalTestExecutionListener.class, WithSecurityContextTestExecutionListener.class })
```
But it fails with:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.corp.AppUser]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.corp.AppUser.<init>()
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:973)
at org.springframework.web.servlet.FrameworkServlet.doDelete(FrameworkServlet.java:885)
which is OK, as AppUser does not have a default constructor, but the framework should actually not create the user, but use the one I passed into the test.
To solve this issue during runtime I had to add AuthenticationPrincipalArgumentResolver as a HandlerMethodArgumentResolver to the web config, but how do I do this in the test case?
Is there any working example for this?
[1] https://spring.io/blog/2014/05/23/preview-spring-security-test-web-security
edit:
The testclass and its configuration looks like this:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = { MyControllerTest.DummyAppConfig.class, MyControllerTest.DummySecurityConfiguration.class })
#TestExecutionListeners(listeners = { ServletTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class, TransactionalTestExecutionListener.class, WithSecurityContextTestExecutionListener.class })
#WebAppConfiguration
public class MyControllerTest {
#Test
public void doTest() throws Exception {
mockMvc.perform(delete("/something/{i}", "123").with(user(new AppUser(...))));
}
#Configuration
public static class DummyAppConfig extends WebMvcConfigurerAdapter {
#Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(new AuthenticationPrincipalArgumentResolver());
}
#Bean
public MyController aController() {
return new MyController();
}
}
#Configuration
#EnableWebSecurity
public static class DummySecurityConfiguration extends WebSecurityConfigurerAdapter {
}
```
And this is the full stacktrace:
```
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.corp.AppUser]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.corp.AppUser.<init>()
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:973)
at org.springframework.web.servlet.FrameworkServlet.doDelete(FrameworkServlet.java:885)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:694)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:62)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:770)
at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:170)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:137)
at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:145)
at com.corp.ControllerTest.doTest(RestCorporateAccountSearchProfilesControllerTest.java:231)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:72)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:81)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:216)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:82)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:60)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:67)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:162)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.corp.AppUser]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.corp.AppUser.<init>()
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:107)
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.createAttribute(ModelAttributeMethodProcessor.java:138)
at org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor.createAttribute(ServletModelAttributeMethodProcessor.java:81)
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:104)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:79)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:157)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:124)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:721)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
... 39 more
Caused by: java.lang.NoSuchMethodException: com.corp.AppUser.<init>()
at java.lang.Class.getConstructor0(Class.java:2800)
at java.lang.Class.getDeclaredConstructor(Class.java:2043)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:104)
... 52 more
```
If you use the MockMvcBuilders.standaloneSetup() method, you can add the resolver to the standalone MockMvc as so:
MockMvcBuilders.standaloneSetup(controller).setCustomArgumentResolvers(new AuthenticationPrincipalArgumentResolver()).build()
I too, had trouble getting it to work with the MockMvcBuilders.webAppContextSetup() method, but standalone worked without concern.
You need to use #EnableWebMvcSecurity on DummySecurityConfiguration in order to get the Spring Security / MVC integration. See http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/#mvc-enablewebmvcsecurity

How to mock SessionFactory or Session by PowerMockito in a project using Spring and Hibernate?

I am working on a project that uses Spring and Hibernate. I have an abstract DAO that contains SessionFactory. I need to mock SessionFactory or Session for my unit test. But I have not been successful so far. Below is the code. Anyone has any idea? Thank you.
Here is my AbstractDAO
public abstract class AbstractDAO {
protected JdbcTemplate jdbcTemplate;
protected SessionFactory sessionFactory;
protected NamedParameterJdbcTemplate namedParameterJdbcTemplate;
...
#Autowired
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}}
And here is my ConcreteDAO
public class LoginDAO extends AbstractDAO implements InitializingBean {
...
public User getLoggedinUserByUserid(Long userid){
log.info("in getLoggedinUserByUserid");
User result = null;
Session session = sessionFactory.openSession();
try {
session.beginTransaction();
result = (User) session.get(User.class, userid);
session.getTransaction().rollback();
session.close();
} catch (Exception e) {
log.error(e,e);
session.getTransaction().rollback();
session.close();
}
return result;
}
...}
and here is my test class
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "LoginDAOTest-context.xml" })
#PrepareForTest({SessionFactory.class, Session.class, Transaction.class})
public class LoginDAOTest2 extends BaseDAO {
private static final Logger log = Logger.getLogger(LoginDAOTest2.class);
#Rule
public PowerMockRule rule = new PowerMockRule();
private LoginDAO loginDAO = new LoginDAO();
private SessionFactory mockedSessionFactory;
private Session mockedSession;
private Transaction mockedTransaction;
#Autowired
public void setSessionFactory(SessionFactory sessionFactoryCore) {
mockedSessionFactory = PowerMockito.mock( sessionFactoryCore.getClass());
mockedSession = PowerMockito.mock(Session.class);
PowerMockito.doReturn(mockedSession).when(mockedSessionFactory).openSession();
PowerMockito.doReturn(mockedTransaction).when(mockedSession).beginTransaction();
loginDAO.setSessionFactory(this.mockedSessionFactory);
}
#Test
public void shouldRollbackInGetLoggedinUserByUseridWhenSessionThrowsException() {
// Given
PowerMockito.doThrow(new Exception()).when(mockedSession).get(User.class, 12L);
// When
loginDAO.getLoggedinUserByUserid(12L);
// Then
verify(mockedTransaction, times(1)).rollback();
}
}
and here is the result of junit.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.aeon.ps.dao.LoginDAOTest2': Injection of autowired dependencies failed; nested exception is java.lang.NoClassDefFoundError: org/mockito/internal/MockitoInvocationHandler
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:287)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:374)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:110)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:321)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:290)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.NoClassDefFoundError: org/mockito/internal/MockitoInvocationHandler
at org.powermock.api.mockito.PowerMockito.mock(PowerMockito.java:138)
at com.aeon.ps.dao.LoginDAOTest2.setSessionFactory(LoginDAOTest2.java:61)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:586)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284)
... 26 more
Caused by: java.lang.ClassNotFoundException: org.mockito.internal.MockitoInvocationHandler
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 35 more
Why don't do this :
#Before
public void setUp() {
mockedSessionFactory = Mockito.mock(SessionFactory.class);
mockedSession = Mockito.mock(Session.class);
mockedTransaction = Mockito.mock(Transaction.class);
Mockito.when(mockedSessionFactory.openSession()).thenReturn(mockedSession);
Mockito.when(mockedSession.beginTransaction()).thenReturn(mockedTransaction);
loginDAO.setSessionFactory(this.mockedSessionFactory);
}
instead of :
#Autowired
public void setSessionFactory(SessionFactory sessionFactoryCore) {
mockedSessionFactory = PowerMockito.mock( sessionFactoryCore.getClass());
mockedSession = PowerMockito.mock(Session.class);
PowerMockito.doReturn(mockedSession).when(mockedSessionFactory).openSession();
PowerMockito.doReturn(mockedTransaction).when(mockedSession).beginTransaction();
loginDAO.setSessionFactory(this.mockedSessionFactory);
}
In addition, it allows you to not use powermock.
Interesting part is here :
Caused by: java.lang.NoClassDefFoundError: org/mockito/internal/MockitoInvocationHandler
at org.powermock.api.mockito.PowerMockito.mock(PowerMockito.java:138)
at com.aeon.ps.dao.LoginDAOTest2.setSessionFactory(LoginDAOTest2.java:61)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:586)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284)
... 26 more
It means that powermock is using an internal class that is not available in the mockito distribution your are using.
From that information I gather you are using Mockito 1.9.5-rc1, with some other recent Powermock release. As of now, Johan din't released a newer version of Powermock that take care of the changes that were made in Mockito 1.9.5-rc1.
These refactoring changes in Mockito were made to help the introduction of the MockMaker API, which allows a third party to provide his own mock factory, bytecode engine or else to create mocks.
See the documentation here : http://docs.mockito.googlecode.com/hg/1.9.5-rc1/org/mockito/Mockito.html
So for now, you should use Mockito 1.9.0 if you are using Powermock.

Resources