#java #spring-boot #junit #mockmvc
Вопрос:
я хочу сопоставить вывод get-запроса и сопоставить с предоставленной вручную строкой json, в основном скопировать одну строку json, выходящую из всего вывода, и протестировать. Перепробовал множество способов, но этого не происходит, я не могу удалить все строки из базы данных, чтобы сопоставить одну строку с другой, поэтому я хочу сопоставить только одну строку json-как показано ниже
{
"instanceName": "",
"read": 1,
"swProduct": "Area 1",
"swProductModule": "Regular 1"
},
Вот мой тестовый код —
@SpringBootTest(classes = TestApplication.class)
@ActiveProfiles("dev")
@AutoConfigureMockMvc
public class SwStatusCheckTest {
@Autowired
private MockMvc mvc;
@IfProfileValue(name = "spring.profiles.active", values = { "dev" })
@Test
@DisplayName("GET Method /SwCheckStatus check success")
public void testStatusSuccess() throws Exception {
MvcResult result = mvc.perform(get("/status/SwCheckStatus"))
.andDo(print())
.andExpect(status().isOk())
.andReturn();
//.andExpect(content().json("{"services":["OutboundMessageService"]}", true));
String actualJson = result.getResponse().getContentAsString();
String expectedJson = "[{"instanceName":"Instance C", "read" : 1, "swProduct" : "Area 3", "swProductModule" : "Spring Boot 3"}]";
assertThat(expectedJson).isIn(actualJson);
}
}
Вывод всего результата Postman json выглядит следующим образом —
[
{
"instanceName": "",
"read": 1,
"swProduct": "Area 1",
"swProductModule": "Regular 1"
},
{
"instanceName": "",
"read": 1,
"swProduct": "Area 1",
"swProductModule": "Regular 2"
},
{
"instanceName": "",
"read": 1,
"swProduct": "Area 1",
"swProductModule": "Spring Boot 1"
},
{
"instanceName": "",
"read": 1,
"swProduct": "Area 1",
"swProductModule": "Spring Boot 2"
},
Intellij говорит-его ожидание и совпадение строк… но тест не удался-проверьте вложение —
[введите описание изображения здесь][1]
Мы высоко ценим любую помощь в проведении теста. [1]: https://i.stack.imgur.com/FE2dT.jpg
Ответ №1:
isIn
предназначен не для сравнения строк, а для массивов.
Вы можете сравнить JSON
as Map
с jackson-databind и Google Guava:
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Maps;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.IfProfileValue;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResu<
@SpringBootTest(classes = TestApplication.class)
@ActiveProfiles("dev")
@AutoConfigureMockMvc
public class SwStatusCheckTest {
@Autowired
private MockMvc mvc;
@IfProfileValue(name = "spring.profiles.active", values = { "dev" })
@Test
@DisplayName("GET Method /SwCheckStatus check success")
public void testStatusSuccess() throws Exception {
MvcResult result = mvc.perform(get("/status/SwCheckStatus"))
.andDo(print())
.andExpect(status().isOk())
.andReturn();
//.andExpect(content().json("{"services":["OutboundMessageService"]}", true));
ObjectMapper mapper = new ObjectMapper();
List<? extends Map<String, Object>> actualJson = mapper.readValue(result.getResponse().getContentAsString(),
List.class);
Map<String, Object> expected = Map.of("instanceName", "", "read", 1, "swProduct", "Area 1", "swProductModule",
"Regular 1");
boolean contains = false;
for (Map<String, Object> a : actualJson) {
boolean res = Maps.difference(a, expected).areEqual();
if (res) {
contains = true;
break;
}
}
assertThat(contains).isTrue();
}
}
Ответ №2:
Если я правильно читаю ваш вопрос, а также изображение, которое вы опубликовали, проблема заключается либо в ожидаемых/фактических строках, либо в условии (утверждении), определенном в тесте. «Фактическое» строковое значение представляет собой массив из нескольких элементов, «ожидаемое» — массив только из одного элемента. Поскольку массив только из одного элемента НЕ содержится в массиве из нескольких элементов, он не будет работать.
Если код изменен таким образом, что «ожидаемое» значение, которое вы ищете, записывается как ПРОСТО объект (без его заключающего массива)
{ ... your object here ... }
Тогда ожидаемое фактическое утверждение «isIn» должно сработать.
Комментарии:
1. мне нужно сопоставить только одну строку… исходя из вывода result.GetResponse().getContentAsString();