Announcement Announcement Module
Collapse
No announcement yet.
Unit Testing with Spring-MVC-Test - @Autowire attributes are null Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Unit Testing with Spring-MVC-Test - @Autowire attributes are null

    Hi guys,

    Im confused when trying to write a unit test for my rest controller as I cannot seem to mock my @Autowire properties in the controller.

    Here is my Test

    Code:
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration()
    public class RegistrationControllerTesting {
    	
    	private MockMvc mockMvc;
    	private LicenseSecurityContextHelper licenseSecurityContextHelper;
    	        
    	private ILicenseAuthentication licenseAuthentication;
    	
    	@Before
    	public void setup() {		
    		licenseAuthentication = mock(LicenseAuthentication.class);
    		mockMvc = MockMvcBuilders.standaloneSetup(new RegistrationController()).build();
    		licenseSecurityContextHelper = mock(LicenseSecurityContextHelper.class);
    		when(licenseSecurityContextHelper.getLicenseAuthentication()).thenReturn(licenseAuthentication);
    	}
    	
    	@Test
    	public void test() throws Exception {		
    		DefaultRequestBuilder requestBuilder = MockMvcRequestBuilders.post("/rest/auth/register")
    			.contentType(MediaType.APPLICATION_JSON)
    			.body(JsonHelperProvider.registrationJson.getBytes());
    		mockMvc.perform(requestBuilder);
    
    	}
    My config in RegistrationControllerTesting-context.xml

    Code:
    <bean id="licenseSecurityContextHelper" class="org.mockito.Mockito" factory-method="mock"> 
     		<constructor-arg value="uk.co.company.common.license.spring.LicenseSecurityContextHelper" />
     	</bean> 
    		
    	<bean id="rollupScheduleService" class="org.mockito.Mockito" factory-method="mock">
    		<constructor-arg value="uk.co.company.product.service.IRollupScheduleService" />
    	</bean>
    	
    	<bean id="productApplicationContextService" class="org.mockito.Mockito" factory-method="mock">
    		<constructor-arg value="uk.co.company.product.service.IproductApplicationContextService" />
    	</bean>
    My controller has autowire fields

    Code:
    @Autowired
    private IproductApplicationContextService productApplicationContextService;
    	
    @Autowired
    private IRollupScheduleService rollupScheduleService;
    	
    @Autowired
    private LicenseSecurityContextHelper licenseSecurityContextHelper;
    However in my controller the object licenseSecurityContextHelper is null i.e

    Code:
    ILicenseAuthentication licenseAuthentication = licenseSecurityContextHelper.getLicenseAuthentication();
    Im confused because the beans seem to be autowired in the log file. I proved this by removing the mocked bean definitions from my xml config and this produces the error

    Code:
    "Could not autowire field: private uk.co.company.product.service.IproductApplicationContextService"
    Can someone please tell me what ive done wrong?
    Last edited by DJC_Spring; Jul 27th, 2012, 05:15 AM.

  • #2
    Hi everyone,

    I resolved the problem and posting the solution here to help others .

    First off my problem was that I was using the standaloneSetup method from the MockMVCBuilders class. This does not use the configuration that I loaded from the @ContextConfiguation annotation (i.e RegistrationControllerTesting-context.xml)

    So it was simply a case of using the MockMVCBuilders.xmlConfigSetup to load in my servlet context and mock objects and remove the @ContextConfiguration.

    So the code:

    This example uses spring-test-mvc and loads in the servlet context from an xml file and injects mocked objects into the controllers @Autowired attributes. It calls a rest service passing in some Json.

    RegistrationControllerTesting-context.xml

    Code:
    <bean id="licenseSecurityContextHelper" class="org.mockito.Mockito" factory-method="mock"> 
     		<constructor-arg value="uk.co.company.common.license.spring.LicenseSecurityContextHelper" />
     	</bean> 
    		
    	<bean id="rollupScheduleService" class="org.mockito.Mockito" factory-method="mock">
    		<constructor-arg value="uk.co.company.product.service.RollupScheduleService" />
    	</bean>
    	
    	<bean id="productApplicationContextService" class="org.mockito.Mockito" factory-method="mock">
    		<constructor-arg value="uk.co.company.product.service.ProductApplicationContextService" />
    	</bean>
    	
    	<mvc:annotation-driven />
    
    	<context:component-scan base-package="uk.co.company.product.mvc" />
    
    	<mvc:resources mapping="/resources/**" location="/resources/" />
    
    	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    		<property name="prefix" value="/WEB-INF/views/" />
    		<property name="suffix" value=".jsp" />
    	</bean>
    Unit Test Case

    Code:
    public class RegistrationControllerTesting {
    	
    	private MockMvc mockMvc;
    	private LicenseSecurityContextHelper licenseSecurityContextHelper;
    	        
    	private ILicenseAuthentication licenseAuthentication;
    	
    	
    	@Before
    	public void setup() {
    		
    		licenseAuthentication = mock(LicenseAuthentication.class);
    		licenseSecurityContextHelper = mock(LicenseSecurityContextHelper.class);
    		mockMvc = MockMvcBuilders.xmlConfigSetup("classpath:uk/co/company/product/mvc/rest/RegistrationControllerTesting-context.xml").build();
    		when(licenseSecurityContextHelper.getLicenseAuthentication()).thenReturn(licenseAuthentication);
    		
    	}
    	
    	@Test
    	public void test() throws Exception {		
    		DefaultRequestBuilder requestBuilder = MockMvcRequestBuilders.post("/rest/auth/register")
    			.contentType(MediaType.APPLICATION_JSON)
    			.body(JsonHelperProvider.registrationJson.getBytes());
    		mockMvc.perform(requestBuilder);
    
    	}
    Controller

    Code:
    public final class RegistrationController {
    	
    	private static final Logger logger = Logger.getLogger(RegistrationController.class);
    	
    	@Autowired
    	private IProductApplicationContextService productApplicationContextService;
    	
    	@Autowired
    	private IRollupScheduleService rollupScheduleService;
    	
    	@Autowired
    	private LicenseSecurityContextHelper licenseSecurityContextHelper;
    
    	
    	public RegistrationController() {
    		logger.info(RegistrationController.class);
    	}
    	
    	@RequestMapping(value = "/register", method=RequestMethod.POST, headers="Content-Type=application/json")
    	@ResponseBody
    	public ProductApplicationContext registerApplication(@RequestBody ApplicationDetails incomingContext) {
    		
    		ILicenseAuthentication licenseAuthentication = licenseSecurityContextHelper.getLicenseAuthentication();
    
    ..
    
    }
    Hope it helps others.

    Comment

    Working...
    X