Reputation: 18108
i am running a unit tests and uses a Service class to perform some business logic. however, the unit tests fails saying that the service class is null dispite setting up the Autorwire annotations for it.
below is my unit test:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "file:src/main/webapp/WEB-INF/FreedomSpring-servlet.xml" })
public class UserControllerTest
{
private UserController controller;
@Inject
private ApplicationContext applicationContext;
private String jsonUser = "{ \"username\":\"jonneymendoza\",\"emailAddress\":\"[email protected]\", \"password\":\"12345678\",\"firstName\":\"jono\", \"surname\":\"richy\", \"country\":\"united kingdom\",\"bio\":\"Bio stuff goes here about the user. where he comes from etc etc. all is well. lets go go go\" }";
@Before
public void setup()
{
controller = new UserController();
assertNotNull(applicationContext);
}
@Test
public void testCreateNewAccount()
{
ResponseEntity<String> response = controller
.createNewAccount(new HttpEntity<String>(jsonUser));
assertEquals(HttpStatus.CREATED, response.getStatusCode());
}
}
Here is the controller i am testing
@Controller
public class UserController
{
@Autowired
private UserService userService;
@RequestMapping(value = "/user", method = RequestMethod.PUT, consumes = "application/json")
public ResponseEntity<String>createNewAccount(HttpEntity<String>request)
{
userService.registerNewUser( JSONObject.fromObject(request.getBody())); //fails here
return new ResponseEntity<String>(null, responseHeaders, HttpStatus.CREATED);
}
}
The service class:
@Service("UserService")
@Transactional
public class UserService implements UserServiceInterface
{
@Override
public void registerNewUser(JSONObject user) throws InvalidDataException, JSONException
{
// parse json object to a User object
User newUser = parseJsonObject(user);
UserDao userDao = new UserDao();
userDao.addNewUser(newUser);
}
}
My service-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<context:annotation-config />
<!-- Define services here -->
<bean id="UserService" class="com.jr.freedom.user.UserService"></bean>
</beans>
My servlett:
<?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-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>database.properties</value>
</list>
</property>
</bean>
<import resource="mvc-config.xml" />
<import resource="service-config.xml" />
<import resource="classpath:datasource-config.xml" />
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<!-- Resolves views selected for rendering by @Controllers to .jsp resources
in the /WEB-INF/views directory -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
<context:component-scan base-package="com.jr.freedom.controllers"></context:component-scan>
</beans>
And finally the error i recieve
java.lang.NullPointerException
at com.jr.freedom.controllers.UserController.createNewAccount(UserController.java:56)
at com.jr.freedom.controllers.UserControllerTest.testCreateNewAccount(UserControllerTest.java:51)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
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)
Upvotes: 2
Views: 806
Reputation: 28706
You need to inject (with some annotation) or retreive userController from the applicationContext so that Spring magic (i.e. injection or userService in your case) works.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "file:src/main/webapp/WEB-INF/FreedomSpring-servlet.xml" })
public class UserControllerTest {
@Autowired
private UserController userController;
@Inject
private ApplicationContext applicationContext;
private String jsonUser = "{ \"username\":\"jonneymendoza\",\"emailAddress\":\"[email protected]\", \"password\":\"12345678\",\"firstName\":\"jono\", \"surname\":\"richy\", \"country\":\"united kingdom\",\"bio\":\"Bio stuff goes here about the user. where he comes from etc etc. all is well. lets go go go\" }";
@Before
public void setup() {
assertNotNull(applicationContext);
assertNotNull(userController);
}
Upvotes: 3