mercredi 21 janvier 2015

Testing Spring Boot MVC with autowired repositories

I have two projects. One called myCore and one called myWeb. myCorecontains all of the beans and repository interfaces. myWeb is simply a JSON api that brings in myCore as a dependency. When I run myWeb everything works fine. When I try to run unit tests against the controllers in myWeb the @Autowired repos are null. I need to find some way for the @Autowired repository interfaces to have the same value as when the application is running, or to mock those objects. Preferably I would like to know how to implement both solutions.


myCore pom.xml:



<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.1.4.RELEASE</version>
</dependency>

<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>2.12.4</version>
</dependency>

<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.6.1.RELEASE</version>
</dependency>


myCore context.xml



<mongo:repositories base-package="com.myOrg.myapp.repo.mongo" />

<mongo:db-factory id="dbfactory" host="removed"
port="removed" dbname="removed" username="removed" password="removed" />

<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoDbFactory" ref="dbfactory" />
</bean>


repo interface:



public interface SiteRepository extends PagingAndSortingRepository<Site, String>{

void findBySomethingCustom(String somethingCustom);
}


In the web project: 'myWeb` pom.xml



<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<start-class>com.myOrg.myApp.Application</start-class>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.myOrg</groupId>
<artifactId>myCore</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>


myWeb config:



@Configuration
@ImportResource("classpath*:/spring/context.xml")
public class Config {}


myWeb controller:



@RestController
@RequestMapping("site")
public class SiteController {

@Autowired
private SiteRepository siteRepo;

@RequestMapping(value = "", method = RequestMethod.GET)
public Iterable<Site> getSites() {
return siteRepo.findAll();
}
}


And finally, the test class:



@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MockServletContext.class)
@WebAppConfiguration
@ContextConfiguration(classes = Config.class)
public class SiteControllerTest {
private MockMvc mvc;

@Before
public void setUp() throws Exception {
mvc = MockMvcBuilders.standaloneSetup(new SiteController()).build();
}

@Test
public void testGetSites() throws Exception {
mvc.perform(
MockMvcRequestBuilders.get("/site"));
}
}


I am getting a null pointer exception in testGetSites() that indicates siteRepo is null. However, navigating to the url of that controller method executes normally.


Again, I either need that to have the value it has when the application runs normally, and/or a way to mock that object so the test can pass(or fail) normally.


Aucun commentaire:

Enregistrer un commentaire