亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用 Mockito 在客戶端測試 POST 請求

使用 Mockito 在客戶端測試 POST 請求

搖曳的薔薇 2022-08-17 12:15:54
我想測試應該向“服務器”發送post請求的post方法(因此我想模擬來自服務器的響應并檢查響應)。另外,我想測試響應是否在正文中包含http狀態OK。問題:我應該如何使用 mockito?客戶端中的“我的帖子”方法(客戶端):public class Client{        public static void sendUser(){        String url = "http://localhost:8080/user/add";        HttpHeaders requestHeaders = new HttpHeaders();        requestHeaders.setContentType(MediaType.APPLICATION_JSON);        requestHeaders.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));        User test = new User();        test.setName("test");        test.setEmail("[email protected]");        test.setScore(205);        RestTemplate restTemplate = new RestTemplate();        HttpEntity<User> request = new HttpEntity<>(test);        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, request, String.class);        if(response.getStatusCode() == HttpStatus.OK){            System.out.println("user response: OK");        }      }  }另一個模塊(服務器端)中的我的控制器:@RestController@RequestMapping("/user")public class UserController{    @Autowired    private UserRepository userRepository;    @PostMapping("/add")    public ResponseEntity addUserToDb(@RequestBody User user) throws Exception    {        userRepository.save(user);        return ResponseEntity.ok(HttpStatus.OK);    }測試:    @RunWith(SpringRunner.class)@ActiveProfiles("test")@SpringBootTest(classes = Client.class)@AutoConfigureMockMvcpublic class ClientTest{    private MockRestServiceServer mockServer;    @Autowired    private RestTemplate restTemplate;     @Autowired    private MockMvc mockMvc;    @Before    public void configureRestMVC()    {        mockServer =                MockRestServiceServer.createServer(restTemplate);    }    @Test    public void testRquestUserAddObject() throws Exception    {        User user = new User("test", "mail", 2255);        Gson gson = new Gson();        String json = gson.toJson(user );        mockServer.expect(once(), requestTo("http://localhost:8080/user/add")).andRespond(withSuccess());}
查看完整描述

2 回答

?
慕尼黑5688855

TA貢獻1848條經驗 獲得超2個贊

根據您的客戶端類,希望提出以下更改建議,以使其更易于測試:


    //  class

    public class Client {


        /*** restTemplate unique instance for every unique HTTP server. ***/

        @Autowired

        RestTemplate restTemplate;


        public ResponseEntity<String> sendUser() {


        String url = "http://localhost:8080/user/add";


        HttpHeaders requestHeaders = new HttpHeaders();

        requestHeaders.setContentType(MediaType.APPLICATION_JSON);

        requestHeaders.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));


        User test = new User();

        test.setName("test");

        test.setEmail("[email protected]");

        test.setScore(205);


        HttpEntity<User> request = new HttpEntity<>(test);


        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, request, String.class);


        if(response.getStatusCode() == HttpStatus.OK){

            System.out.println("user response: OK");

        }

        return response;

      }

  }

然后對于上面的我們朱尼特作為:


@RunWith(MockitoJUnitRunner.class)

public class ClientTest {


  private String RESULT = "Assert result";


  @Mock

  private RestTemplate restTemplate;


  @InjectMocks

  private Client client;


  /**

   * any setting needed before load of test class

   */

  @Before

  public void setUp() {

    // not needed as of now

  }


  // testing an exception scenario

  @Test(expected = RestClientException.class)

  public void testSendUserForExceptionScenario() throws RestClientException {


    doThrow(RestClientException.class).when(restTemplate)

        .exchange(anyString(), any(HttpMethod.class), any(HttpEntity.class), any(Class.class));

    // expect RestClientException

    client.sendUser();

  }


  @Test

  public void testSendUserForValidScenario() throws RestClientException {


    // creating expected response

    User user= new User("name", "mail", 6609); 

    Gson gson = new Gson(); 

    String json = gson.toJson(user); 

    doReturn(new ResponseEntity<String>(json, HttpStatus.OK)).when(restTemplate)

        .exchange(anyString(), any(HttpMethod.class), any(HttpEntity.class), any(Class.class));

    // expect proper response

    ResponseEntity<String> response =

        (ResponseEntity<String>) client.sendUser();

    assertEquals(this.RESULT, HttpStatus.OK, response.getStatusCode());

  }

}

基本上在您的功能中,我們正在做:sendResponse()


// we are getting URL , creating requestHeader

// finally creating HttpEntity<User> request 

// and then passing them restTemplate.exchange 

// and then restTemplate is doing its job to make a HTPP connection and getresponse...

// and then we are prinnting the response... somestuff 

因此,在相應的測試中,我們還應該只測試函數正在執行的操作,因為連接正在被照顧,并且您沒有覆蓋任何工作,因此我們不應該為相同的事情做任何事情......而只是測試我們的代碼/邏輯。restTemplaterestTemplate


最后,為了確保導入看起來像:


可以肯定的是,進口會像這樣:


import org.springframework.http.HttpEntity; 

import org.springframework.http.HttpHeaders; 

import org.springframework.http.HttpMethod; 

import org.springframework.http.HttpStatus; 

import org.springframework.http.MediaType; 

import org.springframework.http.ResponseEntity; 

import org.springframework.web.client.RestTemplate;

希望這有幫助。


查看完整回答
反對 回復 2022-08-17
?
largeQ

TA貢獻2039條經驗 獲得超8個贊

首先是完整代碼(說明如下):


import static org.springframework.test.web.client.ExpectedCount.manyTimes;

import static org.springframework.test.web.client.ExpectedCount.once;

import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;

import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;

import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;

import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;

import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;


@RunWith(SpringRunner.class)

@ActiveProfiles("test")

@SpringBootTest

@AutoConfigureMockMvc

public class MyTestClass {


MockRestServiceServer mockServer;


    @Autowired

    private RestTemplate restTemplate;  //create a bean somewhere. It will be injected here. 


    @Autowired

    private MockMvc mockMvc;


    @Before

    public void configureRestMVC(){

        mockServer =

                MockRestServiceServer.createServer(restTemplate);

    }


    @Test

    public void test0() throws Exception {

        //this is where you would mock the call to endpoint and and response

        mockServer.expect(once(), requestTo("www.example.com/endpoint1"))

        .andRespond(withSuccess());

    ... 

    //here you will actually make a call to your controller. If the service class is making a post call to another endpoint outside, that you just mocked in above statement.

    this.mockMvc.perform(post("www.example2.com/example2endpoint")

                .content(asJsonString(new YouCustomObjectThatYouWantToPost))

                .contentType(MediaType.APPLICATION_JSON))

        .andDo(print()).andExpect(status().isOk())

        .andExpect(content().json(matchResponseAgainstThisObject()));

   }

您需要使用注釋。背后的目的是根本不啟動服務器,而只測試該層下面的層,其中Spring處理傳入的HTTP請求并將其傳遞給您的控制器。這樣,幾乎使用完整的堆棧,并且您的代碼將被調用,就像它處理真正的HTTP請求一樣,但沒有啟動服務器的成本。為此,我們將使用Spring的MockMvc,我們可以通過使用測試類上的注釋來要求為我們注入它。@AutoConfigureMockMvc@AutoConfigureMockMvc


private MockRestServiceServer mockServer;

MockRestServiceServer是客戶端REST測試的主要入口點。用于涉及直接或間接使用 RestTemplate 的測試。提供一種方法來設置將通過 RestTemplate 執行的預期請求,以及要發送回的模擬響應,從而消除了對實際服務器的需求。


mockServer.expect(once(), requestTo("www.example.com/endpoint1"))

    .andRespond(withSuccess());

這是您將設置模擬外部調用的地方。以及設置期望。


this.mockMvc.perform(post("www.example2.com/example2endpoint")..

在這里,您將實際對自己的終結點(在控制器中定義的終結點)進行 rest/api 調用。Spring將命中你的端點,執行你在控制器/服務層中的所有邏輯,當涉及到實際在外面進行調用的部分時,將使用你上面剛剛定義的mockServer。這樣,它完全離線。您從未遇到過實際的外部服務。此外,您將在同一個 mockMvc.perform 方法上附加斷言。


查看完整回答
反對 回復 2022-08-17
  • 2 回答
  • 0 關注
  • 90 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號