Jono
Jono

Reputation: 18108

Spring autowire issue

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

Answers (1)

ben75
ben75

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

Related Questions