在春季测试RestController时,HttpServletRequest为空

时间:2019-05-31 16:21:34

标签: java spring testing

我正在开发Spring Web服务,我需要读取数据并将其设置为拦截器中的Session属性。 当我使用外部客户端测试端点时,一切正常。但是,当我尝试以下代码时,我得到了NullPointerException

@RunWith(SpringRunner.class)
@WebMvcTest(AccountController.class)
public class AccountControllerTest {

private MockMvc mockMvc;

@InjectMocks
private AccountController accountController;

@MockBean
private IncomingInterceptor incomingInterceptor;

@MockBean
private AccountService accountService;

@MockBean
private FileStoreService fileStoreService;

private Gson gson;

@Before
public void setup() {
    gson = new Gson();
    mockMvc = MockMvcBuilders.standaloneSetup(accountController).addInterceptors(incomingInterceptor).build();
}

@Test
public void testAddAccount() throws Exception {
    JsonObject root = new JsonObject();
    root.add("body", gson.toJsonTree(account));

    Mockito.when(accountController.addAccount()).thenReturn(new ResponseEntity<>(1L, HttpStatus.OK));

    MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/account/register")
            .content(root.toString())
            .characterEncoding("utf-8")
            .contentType(MediaType.APPLICATION_JSON))
            .andExpect(MockMvcResultMatchers.status().isOk())
            .andDo(MockMvcResultHandlers.print())
            .andReturn();

    String contentAsString = mvcResult.getResponse().getContentAsString();
    System.out.println("contentAsString = " + contentAsString);
}
}

在拦截器中设置属性时,所有工作均按预期进行,但是当我尝试在AccountController中访问它们时,将引发异常。我已经尝试过使用MockMvcRequestBuilders,但是它也不起作用。

访问属性的代码:

 JsonObject body = (JsonObject) request.getSession().getAttribute("body");           

谢谢!

1 个答案:

答案 0 :(得分:0)

您正在将数据作为RequestBody(而不是会话)的一部分进行发送。要访问RequestBody,您应该尝试执行以下操作。

String requestBody= IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8);

稍后,您可以将字符串转换为JsonObject

JsonObject jsonObject = new JsonParser().parse(requestBody).getAsJsonObject();

现在,如果看到@WebMvcTest,它将自动配置mockMvc。因此,您可以简单地对其进行自动布线,而不必手动对其进行覆盖。

  @Autowired
  private MockMvc mockMvc;

并删除覆盖模拟Mvc的行。

我希望这会有所帮助。