【问题标题】:Spring Testing - java.lang.IllegalArgumentException: Not enough variable values available to expandSpring 测试 - java.lang.IllegalArgumentException:没有足够的变量值可用于扩展
【发布时间】:2015-12-07 13:31:14
【问题描述】:

我正在为下面的 REST 控制器编写单元测试,该控制器采用用户 ID 并向该用户授予权限列表。

    @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'"

我在测试中使用 .param() 方法发送所需的 URL 参数,我做错了什么?我提出了这个可能重复的问题,但没有发现它有多大用处。 Using RestTemplate in Spring. Exception- Not enough variables available to expand

【问题讨论】:

    标签: java spring junit spring-test


    【解决方案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&lt;String&gt;,而不是使用JSONObject,我使用JSONArray并使用content()方法将JSONArray作为字符串发送。

    这是我对测试方法所做的更改。

       @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();
        }
    

    【讨论】:

    • 这很棒。帮助过我。 +1 来自我。谢谢!
    【解决方案2】:
            @Test
    public void getOneContactAPI() throws Exception {
        String id = "8";
        mvc.perform(MockMvcRequestBuilders.get("/api/contact/{id}",id).accept(MediaType.APPLICATION_JSON))
        .andDo(MockMvcResultHandlers.print())
        .andExpect(status().isOk())
        .andExpect(MockMvcResultMatchers.jsonPath("id").exists());
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-16
      • 1970-01-01
      • 2020-01-30
      • 1970-01-01
      • 2019-11-07
      • 1970-01-01
      • 2023-03-30
      相关资源
      最近更新 更多