java - Spring Boot Junit 测试预期为 200,但禁止获取 403

标签 java spring-boot unit-testing junit

我正在 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/

相关文章:

spring-boot - Zuul 网关 - setSendZuulResponse & removeRouteHost

java - 如何从 Mockito 模拟中获取每个方法的调用?

swift - 使用已发布的结果为 ObservableObject ViewModel 编写单元测试

java - 创建新文件与 createTempFile

java - android.os.NetworkOnMainThreadException 里面新线程

java - 如何使用 Android Studio 删除 JsonArray 中的反斜杠 ("\"")?

java - 在 .conf 文件中为 spring boot 应用程序访问环境变量

intellij-idea - spring-boot 无法在 gradle build 上加载 liquibase 更改

javascript - 在 javascript qunit 中模拟 'this'

java - Android 出现奇怪的方框符号