Springboot Junit Test期望200,但被禁止403

时间:2019-12-02 12:35:38

标签: java spring-boot unit-testing junit

我正在Junit测试一个对数据库使用JPA存储库的控制器。我的内存数据库中的H2正常工作,并且我的GET Request映射按预期工作。我的PUT得到403,而我希望得到200。我已经尝试使用带有安全false的AutoConfigureMockMvc进行各种不同的配置,并且还排除了安全性自动配置。

在PUT请求,安全性配置方面是否缺少我的东西,还是需要在令牌周围添加配置?

这是我的Junit测试,当updateTest返回403时,saveTest可以正常工作。

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

    }
}

这是我的控制人,

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

2 个答案:

答案 0 :(得分:0)

为测试配置文件创建以下内容。

@EnableWebSecurity
@Configuration
@EnableGlobalMethodSecurity(jsr250Enabled = true)
class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("root").password("system").roles("SYSTEM");
    }
}

在您的测试课中,

public class DBcontroltest {
...

   @Test
   @WithUserDetails(value = "root")
   public void updateTest() throws Exception {
...
}

请在github上访问此项目,我已经使用spring boot使用spring-security设置了spring boot测试。

测试用例: https://github.com/reflexdemon/shop/blob/master/src/test/java/org/shop/service/CatalogServiceTest.java

配置: https://github.com/reflexdemon/shop/blob/master/src/main/java/org/shop/WebSecurityConfig.java

答案 1 :(得分:0)

通过使用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));