3

我有一个带有设备的 Rest 控制器(设备必须是解析,我使用的是 spring-mobile-device)作为参数。单元测试给了我一个状态 415。

这是代码

@RequestMapping(method = RequestMethod.POST)
public ResponseEntity<?> authenticationRequest(@RequestBody AuthenticationRequestDto authenticationRequest,
        Device device) throws AuthenticationException {

    Authentication authentication = this.authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(
            authenticationRequest.getUsername(), authenticationRequest.getPassword()));
    SecurityContextHolder.getContext().setAuthentication(authentication);

    UserDetails userDetails = this.userDetailsService.loadUserByUsername(authenticationRequest.getUsername());

    String token = this.tokenGenerator.generateToken(userDetails, device);

    return ResponseEntity.ok(new AuthenticationResponseDto(token));
}

单元测试

    ResultActions res = mockMvc.perform(post("/auth", authentication, device).contentType(TestUtil.APPLICATION_JSON_UTF8)
            .content(TestUtil.convertObjectToJsonBytes(authentication)));
    res.andExpect(status().isOk());
4

2 回答 2

1

好吧,基本上我的配置有误。必须以与生产配置相同的方式配置 Web Config 以进行测试,但在语法上有所不同。好吧,我在这个问题上学到了很多关于 MockMVC 配置的知识。

如果您想使用 spring mobile 进行单元测试,这是解决方案。

头等舱

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {WebTestConfig.class})
@WebAppConfiguration
public class WebTestConfigAware {

  @Autowired
  private WebApplicationContext context;

  protected MockMvc mockMvc;

  @Autowired
  private FilterChainProxy springSecurityFilterChain;

  @Before
  public void setup() {
    mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
    DeviceResolverRequestFilter deviceResolverRequestFilter = new DeviceResolverRequestFilter();

    mockMvc = MockMvcBuilders.webAppContextSetup(context)
        .addFilters(this.springSecurityFilterChain, deviceResolverRequestFilter).build();
  }

}

二等舱

@Configuration
@EnableWebMvc
@Import({RootTestConfig.class, WebCommonSecurityConfig.class})
public class WebTestConfig  extends WebMvcConfigurerAdapter{


  @Override
  public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
    argumentResolvers.add(new ServletWebArgumentResolverAdapter(new DeviceWebArgumentResolver()));
    argumentResolvers.add(new SitePreferenceHandlerMethodArgumentResolver());
  }
}

和测试类

public class AuthenticationControllerTest extends WebTestConfigAware {

  @Test
  public void testAuthenticationRequest() throws Exception {
    AuthenticationRequestDto authentication = new AuthenticationRequestDto();
    authentication.setUsername("admin");
    authentication.setPassword("Test1234");

    String jsonAuthentication = TestUtil.convertObjectToJsonString(authentication);

    ResultActions res = mockMvc.perform(post("/auth")
        .contentType(MediaType.APPLICATION_JSON_UTF8_VALUE).content(jsonAuthentication));

    res.andExpect(status().isOk());

  }
于 2017-03-20T20:58:03.070 回答
0

在您的测试课程中,您不正确地构建了您的请求

// a couple of issues here explained below
ResultActions res = mockMvc.perform(post("/auth", authentication, device).contentType(TestUtil.APPLICATION_JSON_UTF8)
                .content(TestUtil.convertObjectToJsonBytes(authentication)));

post("/auth", authentication, device)authentication 和 device 被解释为路径 URI,因此这里不需要它们,您的控制器 URI 没有任何路径 URI 变量。如果您的意图是将 2 个对象作为请求的主体传递,那么您需要修改您的测试请求和控制器请求处理程序。您不能将 2 个对象作为请求的主体传递,您需要将两个对象封装在一个中

class AuthenticationRequest {
     private AuthenticationRequestDto authenticationDto;
     private Device device;

     // constructor, getters and setters
}

在您的控制器中

@RequestMapping(method = RequestMethod.POST)
    public ResponseEntity<?> authenticationRequest(@RequestBody AuthenticationRequest request) throws AuthenticationException {
    AuthenticationRequestDto authenticationDto = request.getAuthenticationDto();
    Device device = request.getDevice();

    // ....
}

同样在您的测试中,您需要传递一个 JSON 对象字符串,将其转换为字节(这就是您得到 415 的原因):

// note the change in the TestUtils, the method being called is convertObjectToJsonString (you'll need to add it)
ResultActions res = mockMvc.perform(post("/auth").contentType(TestUtil.APPLICATION_JSON_UTF8)
        .content(TestUtil.convertObjectToJsonString(new Authenticationrequest(authentication, device))));
于 2017-03-03T17:57:07.770 回答