2017-10-11 55 views
1

下面的測試(我包括兩個類來查看是否可以工作)都沒有調用控制器的問題。我希望它拒絕CORS問題,因爲我沒有添加任何CORS配置。 (然後我想用CORS配置進行測試並通過)。如何在Spring Boot中測試CORS?當我嘗試使用MockMvcBuilders時,儘管起源錯誤,它始終返回200

我該如何強制CORS失敗?

第一次嘗試:

import com.testing.Application; 
import com.testing.config.ControllerConfig; 
import com.testing.controller.MyController; 
import com.testing.dto.TestDateResponse; 
import com.testing.exception.GlobalExceptionHandler; 
import com.testing.service.TestService; 
import com.fasterxml.jackson.databind.ObjectMapper; 
import org.junit.Before; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.mockito.InjectMocks; 
import org.mockito.MockitoAnnotations; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.boot.test.context.SpringBootTest; 
import org.springframework.http.MediaType; 
import org.springframework.test.context.ContextConfiguration; 
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 
import org.springframework.test.context.web.WebAppConfiguration; 
import org.springframework.test.web.servlet.MockMvc; 
import org.springframework.test.web.servlet.ResultActions; 
import org.springframework.test.web.servlet.setup.MockMvcBuilders; 
import org.springframework.web.client.RestTemplate; 
import org.springframework.web.context.ConfigurableWebApplicationContext; 

import java.time.LocalDate; 

import static org.hamcrest.Matchers.equalTo; 
import static org.hamcrest.Matchers.notNullValue; 
import static org.junit.Assert.assertThat; 
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; 
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; 
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringBootTest(classes = Application.class) 
@WebAppConfiguration 
public class TestCORS 
{ 
    @Autowired 
    private ConfigurableWebApplicationContext context; 

    private MockMvc mockMvc; 
    private ObjectMapper objectMapper; 

    @InjectMocks 
    private MyController myController; 

    @Autowired 
    private RestTemplate restTemplate; 

    @Before 
    public void setup() 
    { 
     //Initialize our injected mocks 
     MockitoAnnotations.initMocks(this); 

     //Create a controller 
     myController = new MyController(new TestService(), restTemplate); 

     //Create an environment for it 
     mockMvc = MockMvcBuilders 
      .webAppContextSetup(context) 
      .dispatchOptions(true) 
      .build(); 

     //Create our marshaller 
     objectMapper = new ObjectMapper(); 
    } 

    /** 
    * Tests that we fail when trying to access cross origin 
    * @throws Exception if json unmarshaller cannot parse the response 
    */ 
    @Test 
    public void testValidRequest() throws Exception 
    { 
     String request = "{\"asOfDate\":\"20170210\"}"; 

     //Call to test a date 
     ResultActions actions = mockMvc.perform(
      post("/v1/testdate") 
       .contentType(MediaType.APPLICATION_JSON) 
       .content(request) 

       //CORS HEADERS 
       .header("Access-Control-Request-Method", "DELETE") 
       .header("Origin", "https://evil.com") 
     ); 

     actions.andExpect(status().isOk()) 
      .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)); 

     TestDateResponse response = objectMapper.readValue(actions.andReturn().getResponse().getContentAsString(), TestDateResponse.class); 
     assertThat(response, notNullValue()); 
     // verify date has returned back correctly 
     assertThat(response.getRetDate(), equalTo(LocalDate.of(2017, 02, 10))); 
    } 
} 

第二次嘗試:

import com.testing.config.ControllerConfig; 
import com.testing.controller.MyController; 
import com.testing.dto.TestDateResponse; 
import com.testing.exception.GlobalExceptionHandler; 
import com.testing.service.TestService; 
import com.fasterxml.jackson.databind.ObjectMapper; 
import org.junit.Before; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.mockito.MockitoAnnotations; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.http.MediaType; 
import org.springframework.test.context.ContextConfiguration; 
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 
import org.springframework.test.web.servlet.MockMvc; 
import org.springframework.test.web.servlet.ResultActions; 
import org.springframework.test.web.servlet.setup.MockMvcBuilders; 
import org.springframework.web.client.RestTemplate; 

import java.time.LocalDate; 

import static org.hamcrest.Matchers.equalTo; 
import static org.hamcrest.Matchers.notNullValue; 
import static org.junit.Assert.assertThat; 
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; 
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; 
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(classes = {ControllerConfig.class}) 
public class TestCORS 
{ 
    private MockMvc mockMvc; 
    private ObjectMapper objectMapper; 
    private MyController myController; 

    @Autowired 
    private RestTemplate restTemplate; 

    @Before 
    public void setup() 
    { 
     //Initialize our injected mocks 
     MockitoAnnotations.initMocks(this); 

     //Create a controller 
     myController = new MyController(new TestService(), restTemplate); 

     //Create an environment for it 
     mockMvc = MockMvcBuilders.standaloneSetup(myController) 
      .setControllerAdvice(new GlobalExceptionHandler()) 
      .build(); 

     //Create our marshaller 
     objectMapper = new ObjectMapper(); 
    } 

    /** 
    * Tests that we fail when trying to access cross origin 
    * @throws Exception if json unmarshaller cannot parse the response 
    */ 
    @Test 
    public void testValidRequest() throws Exception 
    { 
     String request = "{\"asOfDate\":\"20170210\"}"; 

     //Call to test a date 
     ResultActions actions = mockMvc.perform(
      post("/v1/testdate") 
       .contentType(MediaType.APPLICATION_JSON) 
       .content(request) 

       //CORS HEADERS 
       .header("Access-Control-Request-Method", "GET") 
       .header("Origin", "http://www.someurl.com") 
     ); 
     actions.andExpect(status().isOk()) 
      .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)); 

     TestDateResponse response = objectMapper.readValue(actions.andReturn().getResponse().getContentAsString(), TestDateResponse.class); 
     assertThat(response, notNullValue()); 
     // verify date has returned back correctly 
     assertThat(response.getRetDate(), equalTo(LocalDate.of(2017, 02, 10))); 
    } 
} 

回答

0

CORS不喜歡的工作。

要檢查CORS,必須對URL執行預檢操作。 這不是一個POST,而是一個OPTIONS請求,針對與CORS頭部完全相同的URL。

通過該調用,如果允許或不允許真正的調用(禁止DELETE),您將收到CORS響應。

類似的東西應該工作:

ResultActions actions = mockMvc.perform(
     options("/v1/testdate")  
      .contentType(MediaType.APPLICATION_JSON) 
      //CORS HEADERS 
      .header("Access-Control-Request-Method", "DELETE") 
      .header("Origin", "https://evil.com") 
    ); 

,然後簡單地斷言的預期響應頭。

+0

我得到這個錯誤:'javax.servlet.ServletException:處理程序沒有適配器[org.springframew[email protected]82c57b3]:DispatcherServlet配置需要包含一個HandlerAdapter來支持這個處理程序' –

+0

您是否在您的RequestController或您的RequestMapping上配置了交叉原點?例如與:@CrossOrigin(origins =「http://not-evil.com」) –

+0

不,我不知道。我需要嗎?這會解決這個錯誤嗎? 有沒有辦法讓自定義的適配器bean擺脫這個錯誤? –

相關問題