我正在 Junit 测试一个使用 JPA 存储库作为数据库的 Controller 。我的内存数据库中的 H2 工作正常,并且我的 GET 请求映射按预期工作。我的 PUT 得到的是 403,而我期望的是 200。我已经使用带有 secure false 的 AutoConfigureMockMvc 尝试了各种不同的配置,并且还排除了安全自动配置。
关于 PUT 请求、安全配置,我是否缺少某些内容,或者需要在 token 周围添加配置?
这是我的 Junit 测试,saveTest 工作正常,而 updateTest 返回 403。
@EnableAutoConfiguration(exclude = SecurityAutoConfiguration.class)
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc(secure = false)
@Import(SecurityConfig.class)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
public class DBcontroltest {
@Autowired
DbRequest dbRequest;
@Autowired
ConnectionRequestRepository connectionRequestRepository;
@Autowired
private MockMvc mockMvc;
private String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
private SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
private Date date;
private String dateFormatted = "2019-11-26T14:33:13.175+0000";
{
try {
date = simpleDateFormat.parse("2019-11-26T14:33:13.175+0000");
} catch (ParseException e) {
e.printStackTrace();
}
}
@Test
public void saveTest() throws Exception {
ConnectionRequest connectionRequest = new ConnectionRequest((long) 1, "bleep", "market", "dev", "conn1", "fun", "java", "styff", "hello", "whoop", date, "dldl");
connectionRequestRepository.save(connectionRequest);
String body = "{\"connectionId\":1,\"requestor\":\"bleep\",\"market\":\"market\",\"platform\":\"dev\",\"environment\":\"conn1\",\"connectionName\":\"fun\",\"connectionType\":\"java\",\"databaseId\":\"styff\",\"databasePwd\":\"hello\",\"email\":\"whoop\",\"requestDate\":\"" + dateFormatted + "\",\"jobStatus\":\"dldl\"}\n" +
" ";
mockMvc.perform(get("/api/selectDB/{connectionId}" ,1))
.andExpect(content().json(body))
.andExpect(status().isOk());
}
@Test
public void updateTest() throws Exception {
ConnectionRequest connectionRequest = new ConnectionRequest((long) 1, "bleep", "market", "dev", "conn1", "connname", "java", "db", "hello", "email@aol.com", date, "done");
connectionRequestRepository.save(connectionRequest);
String body3 = "{\"requestor\":\"NEWGUY\"}";
MockHttpServletRequestBuilder builder =
MockMvcRequestBuilders.put("/api/updateDB/{connectionId}" ,1)
.contentType("application/json")
.content(body3);
System.out.println(connectionRequestRepository.findById((long) 1));
this.mockMvc.perform(builder)
.andExpect(MockMvcResultMatchers.status()
.isOk())
.andDo(MockMvcResultHandlers.print());
System.out.println(connectionRequestRepository.findById((long) 1));
}
}
这是我的 Controller ,
@Data
@RestController
@RequestMapping("/api/")
public class DbRequest {
@Autowired
private ConnectionRequestRepository connectionRequestRepository;
private ConnectionRequest connectionRequest;
@GetMapping("/selectDB/{connectionId}")
public ResponseEntity<ConnectionRequest> getRequestById(@PathVariable("connectionId") Long connectionId) throws Exception {
ConnectionRequest connectionRequest = connectionRequestRepository.findById(connectionId)
.orElseThrow(() -> new Exception("Connection Request " + connectionId + " not found"));
return ResponseEntity.ok().body(connectionRequest);
}
@PutMapping("/updateDB/{connectionId}")
public ResponseEntity<ConnectionRequest> updateConnectionRequest(@PathVariable("connectionId") Long connectionId,
@Valid @RequestBody ConnectionRequest connectionRequestDetails) throws Exception {
long completedDateTime = System.currentTimeMillis();
System.out.println("completeDateTime is " + completedDateTime);
ConnectionRequest connectionRequest = connectionRequestRepository.findById(connectionId)
.orElseThrow(() -> new Exception("Connection Request " + connectionId + " not found"));
System.out.println("value for connectionrequest is " + connectionRequest);
System.out.println("value for connectionrequestdetails is " + connectionRequestDetails);
connectionRequest.setRequestor(connectionRequestDetails.getRequestor());
final ConnectionRequest updatedConnectionRequest = connectionRequestRepository.save(connectionRequest);
return ResponseEntity.ok(updatedConnectionRequest);
}
}
这是运行 junit 测试的输出,数据良好。我已经测试了该应用程序,它按预期工作,只有 Junit 失败。
MockHttpServletRequest:
HTTP Method = PUT
Request URI = /api/updateDB/1
Parameters = {}
Headers = [Content-Type:"application/json;charset=UTF-8"]
Body = {"requestor":"NEWGUY"}
Session Attrs = {org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository.CSRF_TOKEN=org.springframework.security.web.csrf.DefaultCsrfToken@80b6098}
Handler:
Type = null
Async:
Async started = false
Async result = null
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 403
Error message = Forbidden
Headers = [X-Content-Type-Options:"nosniff", X-XSS-Protection:"1; mode=block", Cache-Control:"no-cache, no-store, max-age=0, must-revalidate", Pragma:"no-cache", Expires:"0", X-Frame-Options:"DENY"]
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
java.lang.AssertionError: Status
Expected :200
Actual :403
<Click to see difference>
最佳答案
通过使用 csrf,我能够使其正常工作。
MockHttpServletRequestBuilder builder =
put("/api/updateDB/{connectionId}", 1)
.contentType("application/json")
.content(body3)
.contentType(MediaType.APPLICATION_JSON)
.with(csrf());
System.out.println(connectionRequestRepository.findById((long) 1));
this.mockMvc.perform(builder)
.andExpect(content().json(body))
.andExpect(status().isOk())
.andDo(MockMvcResultHandlers.print());
System.out.println(connectionRequestRepository.findById((long) 1));
关于java - Spring Boot Junit 测试预期为 200,但禁止获取 403,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59139047/