2017-06-26 61 views
1

測試用SpringMVC REST Web服務正在使用Spring MVC中創建RESTful Web服務...MockMvc使用JUnit,的Mockito和Hamcrest

這裏是我的pom.xml:

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

<dependency> 
    <groupId>org.springframework</groupId> 
    <artifactId>spring-test</artifactId> 
    <version>4.0.3.RELEASE</version> 
    <scope>test</scope> 
</dependency> 

<dependency> 
    <groupId>org.springframework</groupId> 
    <artifactId>spring-web</artifactId> 
    <version>4.0.3.RELEASE</version> 
</dependency> 

<dependency> 
    <groupId>org.springframework</groupId> 
    <artifactId>spring-webmvc</artifactId> 
    <version>4.0.3.RELEASE</version> 
</dependency> 

<dependency> 
    <groupId>junit</groupId> 
    <artifactId>junit</artifactId> 
    <version>4.12</version> 
    <scope>test</scope> 
</dependency> 

<dependency> 
    <groupId>org.hamcrest</groupId> 
    <artifactId>hamcrest-all</artifactId> 
    <version>1.3</version> 
    <scope>test</scope> 
</dependency> 

<dependency> 
    <groupId>org.mockito</groupId> 
    <artifactId>mockito-core</artifactId> 
    <version>1.10.19</version> 
    <scope>test</scope> 
</dependency> 

<dependency> 
    <groupId>com.jayway.jsonpath</groupId> 
    <artifactId>json-path-assert</artifactId> 
    <version>0.9.1</version> 
    <scope>test</scope> 
</dependency> 

WEB-INF/web.xml中:

<?xml version="1.0" encoding="UTF-8"?> 
<web-app id="WebApp_ID" version="2.4" 
    xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> 
    <display-name>MyApp</display-name> 
    <welcome-file-list> 
     <welcome-file>index.html</welcome-file> 
     <welcome-file>index.jsp</welcome-file> 
    </welcome-file-list> 
    <servlet> 

     <servlet-name>mvc-dispatcher</servlet-name> 
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
     <load-on-startup>1</load-on-startup> 
    </servlet> 
    <servlet-mapping> 
     <servlet-name>mvc-dispatcher</servlet-name> 
     <url-pattern>/</url-pattern> 
    </servlet-mapping> 

    <context-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value> 
    </context-param> 
</web-app> 

WEB-INF/MVC-調度-servlet.xml中:

<beans xmlns="http://www.springframework.org/schema/beans" 
    <import resource="classpath:database_db.xml" /> 

    <context:component-scan base-package="com.myapp.rest" /> 
    <mvc:annotation-driven /> 

    <bean id="viewResolver" 
     class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
     <property name="prefix"> 
      <value>/WEB-INF/pages/</value> 
     </property> 
     <property name="suffix"> 
      <value>.jsp</value> 
     </property> 
    </bean> 
</beans> 

的src /主/資源/ database_db.xml:

<beans xmlns="http://www.springframework.org/schema/beans"> 
    <bean id="dataSourceDB" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> 
     <property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property> 
     <property name="url"><value>jdbc:mysql://localhost/mydatabase?zeroDateTimeBehavior=convertToNull</value></property> 
     <property name="username"><value>root</value></property> 
     <property name="password"><value></value></property> 
    </bean> 
</beans> 

UserController中:

@Controller 
@RequestMapping("/v2") 
public class UserController { 

    private final UserDAO dao; 

    @Autowired 
    public UserController(UserDAO dao) { 
     this.dao = dao; 
    } 

    @RequestMapping(value = "users/appId", method = RequestMethod.GET) 
    public @ResponseBody Object getUserDetails(@PathVariable String appId) { 
     Object response = null; 
     response = dao.getUser(appId); 
     return response; 
    } 
} 

UserDAO的:

@Repository 公共類的UserDAO {

private JdbcTemplate jdbcTemplate; 

@Autowired 
public UserDAO(@Qualifier("dataSourceDB") DataSource dataSource) { 
    this.jdbcTemplate = new JdbcTemplate(dataSource); 
} 

// Various get and finder methods 

}

的src/test/java下:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = "classpath:**/mvc-dispatcher-servlet.xml") 
@WebAppConfiguration 
public class UserControllerTest { 

    @Autowired 
    private WebApplicationContext ctx; 

    private MockMvc mockMvc; 

    @InjectMocks 
    private UserController userController; 

    @Before 
    public void setUp() { 
     MockitoAnnotations.initMocks(this); 
     mockMvc = MockMvcBuilders.standaloneSetup(userController).build(); 
    } 

    @Test 
    public void appUser() throws Exception { 
     String appId = "1234FD57"; 

     mockMvc.perform(get("/v2/users/{appId}", appId) 
         .accept(MediaType.APPLICATION_JSON)) 
         .andDo(print()) 
         .andExpect(status().isOk()); 
    } 
} 

下面是輸出:

------------------------------------------------------- 
T E S T S 
------------------------------------------------------- 
Running com.myapp.rest.controllers.UserControllerTest 

MockHttpServletRequest: 
     HTTP Method = GET 
     Request URI = /v2/users/1234FD57 
      Parameters = {} 
      Headers = {Accept=[application/json]} 

      Handler: 
       Type = com.myapp.rest.controllers.UserController 
       Method = public java.lang.Object com.myapp.rest.controllers.UserController.getUserDetails(java.lang.String) 

       Async: 
    Was async started = false 
     Async result = null 

    Resolved Exception: 
       Type = null 

     ModelAndView: 
      View name = null 
       View = null 
       Model = null 

      FlashMap: 

MockHttpServletResponse: 
       Status = 200 
     Error message = null 
      Headers = {} 
     Content type = null 
       Body = 
     Forwarded URL = null 
     Redirected URL = null 
      Cookies = [] 
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.751 sec 

的測試運行,但身體不包含任何JSON(注意一下它的空白)...

當我改變我的測試方法的內容:

mockMvc.perform(get("/v2/users/{appId}",appId) 
        .accept(MediaType.APPLICATION_JSON)) 
        .andExpect(status().isOk()) 
        .andExpect(jsonPath("$[1].userId", is("1234FD57"))); 

收到以下錯誤:

Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.766 sec <<< FAILURE! 

user(com.myapp.rest.controllers.UserControllerTest) Time elapsed: 0.157 sec <<< ERROR! 
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.myapp.rest.controllers.UserControllerTest': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: 

Could not autowire field: private com.myapp.rest.controllers.UserController 
    com.myapp.rest.controllers.UserControllerTest.userController; nested exception is org.springframework.beans.factory 
    NoSuchBeanDefinitionException: No qualifying bean of type [com.myapp.rest.controllers.UserController] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.mockito.InjectMocks(), @org.springframework.beans.factory.annotation.Autowired(required=true)} 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties 

它就像深藏不露的「身體」打印()語句沒有JSON ...我得到非常接近,沒有人知道我的是什麼了嗎?

+0

不知道爲什麼您的請求正在由正確的處理程序處理,但您的請求映射在路徑變量周圍缺少'{}'。它應該是 '@RequestMapping(value =「users/{appId}」,method = RequestMethod.GET)'@ ResponseBodyObject'是什麼?它不應該是'@ ResponseBody'嗎? – alfcope

+0

這是一個錯字 - 現在編輯它和它的固定。 –

回答

0

既然你使用Spring 4.0.3工作,你必須使用舊jsonpath 0.9.1,請參閱https://jira.spring.io/browse/SPR-12299

+0

謝謝你,我將它改爲0.9.1,現在又有了一個新的錯誤...將很快更新我的帖子,並帶來新的錯誤。 –

0

我不認爲你是初始化你的UserController的在您的測試。你可以:

  1. 在測試中自己初始化它。 UserController userController = new UserController();
  2. @Autowire UserController。但是您還需要將組件掃描的配置包含到@ContextConfiguration中
+0

我剛剛嘗試了你所說的......只是更新了帖子,向你展示了使用你的建議發生了什麼。現在它給我Bean接線問題。 –

+0

對啊,你還需要將你的組件掃描的配置添加到@ContextConfiguration中。或者你可以不自動調用它,只是在測試中做UserController userController = new UserController() – Plog

+0

控制器的Autowire失敗...在實例化UserController後我該做什麼?你能否提供一個組件掃描到@ContextConfiguration的例子(需要在那裏)? –