মকএমভিসি সহ প্রতিক্রিয়া বশে স্ট্রিং কীভাবে চেক করবেন


243

আমার সাধারণ ইন্টিগ্রেশন পরীক্ষা আছে have

@Test
public void shouldReturnErrorMessageToAdminWhenCreatingUserWithUsedUserName() throws Exception {
    mockMvc.perform(post("/api/users").header("Authorization", base64ForTestUser).contentType(MediaType.APPLICATION_JSON)
        .content("{\"userName\":\"testUserDetails\",\"firstName\":\"xxx\",\"lastName\":\"xxx\",\"password\":\"xxx\"}"))
        .andDo(print())
        .andExpect(status().isBadRequest())
        .andExpect(?);
}

শেষ লাইনে আমি প্রত্যাশিত স্ট্রিংয়ের সাথে প্রতিক্রিয়ার বর্ধিত স্ট্রিংটির তুলনা করতে চাই

এবং প্রতিক্রিয়া হিসাবে আমি পেতে:

MockHttpServletResponse:
          Status = 400
   Error message = null
         Headers = {Content-Type=[application/json]}
    Content type = application/json
            Body = "Username already taken"
   Forwarded URL = null
  Redirected URL = null

বিষয়বস্তু (), বডি () দিয়ে কিছু কৌশল চেষ্টা করেও কিছুই কার্যকর হয়নি।


19
ঠিক যেমন পরামর্শ হিসাবে, 400 স্ট্যাটাস কোডটি এমন কিছুর জন্য ফেরত দেওয়া উচিত নয় "Username already taken"। এটি 409 সংঘাতের বেশি হওয়া উচিত।
সোতিরিওস ডেলিমনোলিস

থ্যাঙ্কস - এই পরীক্ষার লক্ষ্য হ'ল এই জাতীয় জিনিসগুলি নির্দিষ্ট করা।
pbaranski

উত্তর:


357

এ হিসাবে সামগ্রীটি পেতে আপনি andReturn()ফিরে আসা MvcResultজিনিসটিকে কল করতে এবং ব্যবহার করতে পারেন String

নিচে দেখ:

MvcResult result = mockMvc.perform(post("/api/users").header("Authorization", base64ForTestUser).contentType(MediaType.APPLICATION_JSON)
            .content("{\"userName\":\"testUserDetails\",\"firstName\":\"xxx\",\"lastName\":\"xxx\",\"password\":\"xxx\"}"))
            .andDo(MockMvcResultHandlers.print())
            .andExpect(status().isBadRequest())
            .andReturn();

String content = result.getResponse().getContentAsString();
// do what you will 

7
@ টিমবিঃ আপনি কি স্পষ্ট করে বলতে পারেন? একটি @RestControllerইঙ্গিত দেয় যে সমস্ত হ্যান্ডলারের পদ্ধতিগুলি স্পষ্টতই টীকাযুক্ত @ResponseBody। এর অর্থ হ'ল স্প্রিং HttpMessageConverterহ্যান্ডলারের রিটার্ন মানটি সিরিয়ালায়িত করতে এবং প্রতিক্রিয়াতে লিখতে ব্যবহার করবে। আপনি শরীরের সাথে খুব পেতে পারেন content()
সোটিরিওস ডেলিমনোলিস

5
@ সোতিরিওস ডেলিমনোলিস সঠিক ... আমি এখনই জেএসএন-এর দিকে ফিরে দেখছি getContentAsString()যা আমার- @RestControllerস্বীকৃত নিয়ামক থেকে এসেছে ।
পল

আমি দেখেছি কি আমি ত্রুটি বার্তা খুঁজছেন ছিল:result.getResponse().getErrorMessage()
whistling_marmot

এবং রিটারন () নাল মানটি ফিরিয়ে দিচ্ছে
গিরিরাজ

@Giriraj andReturnএকটি ফিরতি MvcResultjavadoc উল্লেখিত হিসাবে, এখানে
সোটিরিওস ডেলিমানলিস

105

@ সোরিরিওস ডেলিমনোলিস উত্তরটি কাজটি করে তবে আমি এই মকএমভিসি দৃser়তার মধ্যে স্ট্রিংগুলির তুলনা করতে চাইছিলাম

সুতরাং এটি এখানে

.andExpect(content().string("\"Username already taken - please try with different username\""));

অবশ্যই আমার দৃ fail়তা ব্যর্থ:

java.lang.AssertionError: Response content expected:
<"Username already taken - please try with different username"> but was:<"Something gone wrong">

কারণ:

  MockHttpServletResponse:
            Body = "Something gone wrong"

সুতরাং এটি প্রমাণ করে যে এটি কাজ করে!


17
যদি কেউ, ডায়নামিক ID- র সঙ্গে বার্তা মত আমি করেছিলাম, এটা সহায়কভাবে জানি যে স্ট্রিং () মেথড একটি hamcrest গ্রহণ containsString মিলকারীর:.andExpect(content().string(containsString("\"Username already taken");
molholm

4
@ টিমবিথ, এটি ভুল। যদি আপনার কোনও সমস্যা হয়ে থাকে তবে আপনার এটি প্রশ্ন হিসাবে পোস্ট করা উচিত কারণ এটি অবশ্যই প্রত্যাশিত আচরণ নয় এবং এটি আমার নিজের কোডেও সাক্ষ্য দেওয়া আচরণ নয়।
পল

2
শুধু নোট করুন আমদানি হয় org.hamcrest.Matchers.containsString()
membersound

আমি org.hamcrest.Matchers.equalToIgnoringWhiteSpace()সমস্ত সাদা-স্থানের অক্ষরগুলিকে উপেক্ষা করতে ম্যাচার ব্যবহার করেছি । হতে পারে এটি
কারওর

66

স্প্রিং মকএমভিসি এখন জেএসএনের জন্য সরাসরি সমর্থন পেয়েছে। সুতরাং আপনি কেবল বলেছেন:

.andExpect(content().json("{'message':'ok'}"));

এবং স্ট্রিং তুলনা থেকে ভিন্ন, এটি "অনুপস্থিত ক্ষেত্র xyz" বা "বার্তা প্রত্যাশিত 'ঠিক আছে' 'নোক' এর মতো কিছু বলবে।

এই পদ্ধতিটি বসন্ত ৪.১-এ চালু হয়েছিল।


2
আপনি একটি সম্পূর্ণ উদাহরণ প্রদান করতে পারেন? ContentRequestMatchersএই বৈশিষ্ট্যটিও সমর্থন করার দরকার নেই ?
জারথুস্ত্রা

49

এই উত্তরগুলি পড়া, আমি স্প্রিং সংস্করণ 4.x সম্পর্কিত অনেক কিছুই দেখতে পাচ্ছি, আমি বিভিন্ন কারণে সংস্করণ 3.2.0 ব্যবহার করছি। সুতরাং সরাসরি জেসন সমর্থন মত জিনিসগুলি content()সম্ভব নয়।

আমি দেখতে পেয়েছি যে ব্যবহার MockMvcResultMatchers.jsonPathসত্যিই সহজ এবং একটি ট্রিট কাজ করে। এখানে একটি পোস্ট পদ্ধতি পরীক্ষা করার একটি উদাহরণ রয়েছে।

এই সমাধানটির সাথে বোনাসটি হ'ল আপনি এখনও গুণাবলীর সাথে মিল করছেন, পুরো জেসন স্ট্রিং তুলনাগুলিতে নির্ভর করছেন না।

(ব্যবহার org.springframework.test.web.servlet.result.MockMvcResultMatchers)

String expectedData = "some value";
mockMvc.perform(post("/endPoint")
                .contentType(MediaType.APPLICATION_JSON)
                .content(mockRequestBodyAsString.getBytes()))
                .andExpect(status().isOk())
                .andExpect(MockMvcResultMatchers.jsonPath("$.data").value(expectedData));

অনুরোধের বডিটি কেবল একটি জসন স্ট্রিং ছিল, যা আপনি চাইলে সহজেই একটি আসল জসন মক ডেটা ফাইল থেকে লোড করতে পারেন, তবে আমি এটি এখানে অন্তর্ভুক্ত করি নি কারণ এটি প্রশ্ন থেকে বিচ্যুত হবে।

আসল জসনটি ফিরে আসার মতো দেখতে পেত:

{
    "data":"some value"
}

".andExpect (MockMvcResultMatchers.jsonPath (" জন্য খ্যাতি। $ তথ্য "।) মান (expectedData))"
user1697575

28

বসন্তের টিউটোরিয়াল থেকে নেওয়া

mockMvc.perform(get("/" + userName + "/bookmarks/" 
    + this.bookmarkList.get(0).getId()))
    .andExpect(status().isOk())
    .andExpect(content().contentType(contentType))
    .andExpect(jsonPath("$.id", is(this.bookmarkList.get(0).getId().intValue())))
    .andExpect(jsonPath("$.uri", is("http://bookmark.com/1/" + userName)))
    .andExpect(jsonPath("$.description", is("A description")));

is থেকে উপলব্ধ import static org.hamcrest.Matchers.*;

jsonPath থেকে উপলব্ধ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;

এবং jsonPathরেফারেন্স এখানে পাওয়া যাবে


1
আমি পেতে error: incompatible types: RequestMatcher cannot be converted to ResultMatcher জন্য.andExpect(content().contentType(contentType))
ইয়ান ভন

@ ইয়ানওয়াগান মকএমভিসিআরসাল্টম্যাটচার্সস কনটেন্ট ()। কন্টেন্টটাইপ (কনটেন্টটাইপ)
রাজকুমার

23

স্প্রিং সিকিউরিটির @WithMockUserএবং হ্যামক্রাস্টের containsStringম্যাচার একটি সহজ এবং মার্জিত সমাধানের জন্য তোলে:

@Test
@WithMockUser(roles = "USER")
public void loginWithRoleUserThenExpectUserSpecificContent() throws Exception {
    mockMvc.perform(get("/index"))
            .andExpect(status().isOk())
            .andExpect(content().string(containsString("This content is only shown to users.")));
}

গিথুবের আরও উদাহরণ


4

এখানে কীভাবে JSON প্রতিক্রিয়া পার্স করা যায় এবং কীভাবে JSON আকারে বিনের সাথে একটি অনুরোধ প্রেরণ করা যায় তার একটি উদাহরণ এখানে রয়েছে:

  @Autowired
  protected MockMvc mvc;

  private static final ObjectMapper MAPPER = new ObjectMapper()
    .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
    .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
    .registerModule(new JavaTimeModule());

  public static String requestBody(Object request) {
    try {
      return MAPPER.writeValueAsString(request);
    } catch (JsonProcessingException e) {
      throw new RuntimeException(e);
    }
  }

  public static <T> T parseResponse(MvcResult result, Class<T> responseClass) {
    try {
      String contentAsString = result.getResponse().getContentAsString();
      return MAPPER.readValue(contentAsString, responseClass);
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  @Test
  public void testUpdate() {
    Book book = new Book();
    book.setTitle("1984");
    book.setAuthor("Orwell");
    MvcResult requestResult = mvc.perform(post("http://example.com/book/")
      .contentType(MediaType.APPLICATION_JSON)
      .content(requestBody(book)))
      .andExpect(status().isOk())
      .andReturn();
    UpdateBookResponse updateBookResponse = parseResponse(requestResult, UpdateBookResponse.class);
    assertEquals("1984", updateBookResponse.getTitle());
    assertEquals("Orwell", updateBookResponse.getAuthor());
  }

আপনি এখানে দেখতে পাচ্ছেন এটি Bookহ'ল একটি অনুরোধ ডিটিও এবং এটি জেএসএন UpdateBookResponseথেকে পার্স করা একটি প্রতিক্রিয়া অবজেক্ট। আপনি জ্যাকসনের ObjectMapperকনফিগারেশনটি পরিবর্তন করতে চাইতে পারেন ।


2
String body = mockMvc.perform(bla... bla).andReturn().getResolvedException().getMessage()

এটি আপনাকে প্রতিক্রিয়া দেবে। আপনার ক্ষেত্রে "ব্যবহারকারীর নাম ইতিমধ্যে নেওয়া হয়েছে"।


চাকার ব্যাখ্যা? এটি প্রয়োজন বা আপনি মন্তব্যে এ জাতীয় উত্তরটি দিতে পারেন
111123237

2

এখানে আরও মার্জিত উপায়

mockMvc.perform(post("/retrieve?page=1&countReg=999999")
            .header("Authorization", "Bearer " + validToken))
            .andExpect(status().isOk())
            .andExpect(content().string(containsString("regCount")));

2

স্ট্রিং হিসাবে প্রতিক্রিয়া ডেটা পেতে আপনি 'getContentAsString' পদ্ধতি ব্যবহার করতে পারেন।

    String payload = "....";
    String apiToTest = "....";

    MvcResult mvcResult = mockMvc.
                perform(post(apiToTest).
                content(payload).
                contentType(MediaType.APPLICATION_JSON)).
                andReturn();

    String responseData = mvcResult.getResponse().getContentAsString();

আপনি পরীক্ষার আবেদনের জন্য এই লিঙ্কটি উল্লেখ করতে পারেন ।


1

একটি সম্ভাব্য পদ্ধতির সহজভাবে gsonনির্ভরতা অন্তর্ভুক্ত করা হয় :

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
</dependency>

এবং আপনার যাচাইকরণ করতে মান পার্স করুন:

@RunWith(SpringRunner.class)
@WebMvcTest(HelloController.class)
public class HelloControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private HelloService helloService;

    @Before
    public void before() {
        Mockito.when(helloService.message()).thenReturn("hello world!");
    }

    @Test
    public void testMessage() throws Exception {
        MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.get("/"))
                .andExpect(status().isOk())
                .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON_VALUE))
                .andReturn();

        String responseBody = mvcResult.getResponse().getContentAsString();
        HelloController.ResponseDto responseDto
                = new Gson().fromJson(responseBody, HelloController.ResponseDto.class);
        Assertions.assertThat(responseDto.message).isEqualTo("hello world!");
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.