2015-12-07 34 views
2

我正在爲以下REST控制器編寫單元測試,該控制器需要一個用戶標識並授予該用戶的權限列表。Spring測試 - java.lang.IllegalArgumentException:沒有足夠的變量值可用於擴展

@RestController 
    @RequestMapping("/user") 
    @Api(value = "User", description = "User API") 
    public class UserController{ 

    // some code 

     @RequestMapping(method = RequestMethod.POST, value = "/{userId}/grantAuthz") 
     @ApiOperation(value = "GrantAuthz", notes = "Grant Authorization") 
     public Collection<UserEntity.UserAuthz> grantAuthz(@PathVariable("userId") String userId, 
                  @RequestBody ArrayList<String> authorities) { 
      UserEntity userEntity = userRepository.findOne(userId); 
      if(userEntity == null) { 
       //TODO: throw and send resource not found 
       return null; 
      } 
      log.debug("Authorities to be granted to user " + userId + " are : " + authorities); 
      for(String authz : authorities) { 
       log.debug("Adding Authorization " + authz); 
       userEntity.addUserAuthz(authz); 
      } 
      userRepository.save(userEntity); 
      return userEntity.getAuthorities(); 
     } 
} 

我寫了下面的單元測試的UserController的

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(classes = Application.class) 
@WebAppConfiguration 
public class UserControllerTest { 
    private final Log log = LogFactory.getLog(getClass()); 
    private MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(), 
      MediaType.APPLICATION_JSON.getSubtype(), 
      Charset.forName("utf8")); 

    private MockMvc mockMvc; 
    private HttpMessageConverter mappingJackson2HttpMessageConverter; 
    private final String USER_URL = "/{userId}/grantAuthz"; 
    private final String USER_ID = "111"; 
    private final String USER_NAME = "MockUser"; 

    @Autowired 
    private WebApplicationContext webApplicationContext; 
    @Autowired 
    private UserRepository userRepository; 

    private String createdToken = null; 

    @Autowired 
    void setConverters(HttpMessageConverter<?>[] converters) { 
     this.mappingJackson2HttpMessageConverter = Arrays.asList(converters).stream().filter(
       hmc -> hmc instanceof MappingJackson2HttpMessageConverter).findAny().get(); 

     Assert.assertNotNull("the JSON message converter must not be null", 
       this.mappingJackson2HttpMessageConverter); 
    } 

    @Before 
    public void setup() throws Exception { 
     this.mockMvc = webAppContextSetup(webApplicationContext).build(); 
    } 

    @Test 
    public void testGrantAuthorizationForUser() throws Exception{ 
     Optional<UserEntity> userEntityAuthz = userRepository.findOneByUsername(USER_NAME); 
     Set<String> expectedAuthzList = (LinkedHashSet)userEntityAuthz.get().getAuthorizations(); 

     List<String> grantList = new ArrayList<>(); 
     grantList.add("ABC"); 
     grantList.add("DEF"); 
     grantList.add("GHI"); 
     grantList.add("JKL"); 
     grantList.add("MNO"); 
     grantList.add("PQR"); 
     grantList.add("STU"); 
     grantList.add("VWX"); 
     grantList.add("YZA"); 

     JSONObject json = new JSONObject(); 
     json.put("grantList",grantList); 

     MvcResult grantAuthzResult = mockMvc.perform(MockMvcRequestBuilders.post(USER_URL) 
       .contentType(contentType) 
       .param("userId",USER_ID) 
       .param("authorities",json.toString())) 
       .andExpect(status().isOk()) 
       .andDo(print()) 
       .andReturn(); 
    } 
} 

執行時,我的測試是拋出非法參數異常:

「沒有足夠的變量可以展開「的價值觀userId'「

我發送所需的URL參數在測試中使用.param()方法,我做錯了什麼?我認爲這可能是重複的問題,但沒有發現它很有用。 Using RestTemplate in Spring. Exception- Not enough variables available to expand

回答

1

我發現我做錯了,使用param()方法不是正確的方法,因爲我的控制器方法中有@PathVariable@RequestBody作爲參數。

public Collection<UserEntity.UserAuthz> grantAuthz(@PathVariable("userId") String userId, 
                  @RequestBody ArrayList<String> authorities) { 

所以我在測試的post()方法通過@PathVariable

MockMvcRequestBuilders.post(USER_URL,USER_ID) 

由於所需類型是@RequestBody ArrayList<String>,而不是使用我用JSONArray和所使用的內容()方法來發送JSONArray作爲字符串JSONObject

以下是我對測試方法所做的更改。

@Test 
    public void testGrantAuthorizationForUser() throws Exception{ 
     Optional<UserEntity> userEntityAuthz = userRepository.findOneByUsername(USER_NAME); 
     Set<String> expectedAuthzList = (LinkedHashSet)userEntityAuthz.get().getAuthorizations(); 

     List<String> grantList = new ArrayList<>(); 
     grantList.add("ABC"); 
     grantList.add("DEF"); 
     grantList.add("GHI"); 
     grantList.add("JKL"); 
     grantList.add("MNO"); 
     grantList.add("PQR"); 
     grantList.add("STU"); 
     grantList.add("VWX"); 
     grantList.add("YZA"); 

     JSONArray json = new JSONArray(); 

     MvcResult grantAuthzResult = mockMvc.perform(MockMvcRequestBuilders.post(USER_URL,USER_ID) 
       .contentType(contentType) 
       .content(json.toString())) 
       .andExpect(status().isOk()) 
       .andDo(print()) 
       .andReturn(); 
    }