Для написания теста для определенной функции мне нужно преобразовать строку, содержащую [], в JsonNode.
Проблема в том, что при сопоставлении его с JsonNode кажется, что к нему добавляются дополнительные кавычки.
Я ожидаю "[]", но получаю "" [] "", что приводит к провалу теста. Когда я отлаживаю код в нормальном режиме работы, я получаю только «[]» при тестировании кода с помощью Postman вместо неработающего «« [] »», которое я получаю только во время тестов.
Так выглядит мой DTO в Spring Boot
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;
public class PostLabelDTO {
private final String templateId;
private final String labels;
@JsonCreator
public PostLabelDTO(
final @JsonProperty("templateId") String templateId,
final @JsonProperty("labels") JsonNode labels
) {
this.templateId = templateId;
this.labels = labels.toString();
}
public String getId() {
return templateId;
}
public String getData() {
return labels;
}
}
Мой тест должен подделать этот объект со свойствами, чтобы передать его методу, который будет протестирован.
Мой тест выглядит так:
@Test
public void getEmptyDocumentException() throws InvalidBarcodeException, EmptyStringException, InvalidBarcodeGeometryException, EmptyFieldException, TemplateNotFoundException, InvalidBarcodeStrategyException {
//defining an ID for the templateId JsonProperty
final String templateId = "fj2j931j2ijd1";
//this is the "labels" JsonNode that gets sent in through the Post request
//i checked 10 times how the value comes into the DTO and it was always "[]" (empty labels (document) object, for which I wrote this test for)
final String jsonString = "[]";
ObjectMapper mapper = new ObjectMapper();
mapper.enable(JsonParser.Feature.ALLOW_MISSING_VALUES);
JsonNode labels = mapper.valueToTree(jsonString);
//when I do this, the "[]" which is normally passed into the PostLabelDTO, becomes ""[]"", so there are extra quotes added
PostLabelDTO dto = new PostLabelDTO(templateId, labels);
final Document document = new Document(dto, templateRepository);
Exception resultingException = null;
try {
document.getPDF();
} catch (Exception e) {
e.printStackTrace();
assertThat(resultingException).isExactlyInstanceOf(EmptyDocumentException.class);
}
}
Итак, в основном я попытался поместить указанный выше Json в новый экземпляр PostLabelDTO в качестве объекта JsonNode labels для целей тестирования, но это не сработало.
Это запрос, с которым он работает через почтальона (работает как в, выдает правильное исключение)
{
"templateId":"5b1140608134691d1804e74e",
"labels":[]
}
Итак, в основном я попытался поместить указанный выше Json в новый экземпляр PostLabelDTO в качестве объекта JsonNode labels для целей тестирования, но это не сработало.
Это рабочий запрос (который возвращает PDF-файл с метками с меткой на каждой странице)
{
"templateId": "5b1140608134691d1804e74e",
"labels": [{
"data": {
"Ivolgnr": "Volgnr",
"Ilkw-nr": "Ilkw-nr",
"bedrijf": "Hornbach",
"wagenNr": "13513542626",
"barcode": {
"waarde": "9780471117094"
},
"leverdatumVan": "x",
"leverdatumNaar": "x",
"orderList": [{
"order": [{
"articlenumber": "29-840-4512"
},
{
"description": "Mooie grote plant"
},
{
"ordernumber": "3584479012860361"
},
{
"amount": "20"
},
{
"sellprice": "€5,00"
},
{
"deliverydate": "01-09-2018"
}
]
},
{
"order": [{
"articlenumber": "29-840-4512"
},
{
"description": "Mooie grote plant"
},
{
"ordernumber": "3584479012860361"
},
{
"amount": "20"
},
{
"sellprice": "€5,00"
},
{
"deliverydate": "01-09-2018"
}
]
},
{
"order": [{
"articlenumber": "29-840-4512"
},
{
"description": "Mooie grote plant"
},
{
"ordernumber": "3584479012860361"
},
{
"amount": "20"
},
{
"sellprice": "€5,00"
},
{
"deliverydate": "01-09-2018"
}
]
},
{
"order": [{
"articlenumber": "29-840-4512"
},
{
"description": "Mooie grote plant"
},
{
"ordernumber": "3584479012860361"
},
{
"amount": "20"
},
{
"sellprice": "€5,00"
},
{
"deliverydate": "01-09-2018"
}
]
},
{
"order": [{
"articlenumber": "29-840-4512"
},
{
"description": "Mooie grote plant"
},
{
"ordernumber": "3584479012860361"
},
{
"amount": "20"
},
{
"sellprice": "€5,00"
},
{
"deliverydate": "01-09-2018"
}
]
}
]
}
}, {
"data": {
"Ivolgnr": "22324rff",
"Ilkw-nr": "246426246",
"bedrijf": "bedrijfffff",
"wagenNr": "wagennrrrrrrr",
"barcode": {
"waarde": "9780471117094"
},
"leverdatumVan": "x",
"leverdatumNaar": "x",
"orderList": [{
"order": [{
"articlenumber": "a"
},
{
"description": "b"
},
{
"ordernumber": "c"
},
{
"amount": "d"
},
{
"sellprice": "e"
},
{
"deliverydate": "f"
}
]
}]
}
}]
}
ВНИМАНИЕ Схема метки (называемая данными для каждой метки в этом запросе) всегда может варьироваться в зависимости от того, какой шаблон используется для заполнения. Таким образом, нет возможности создать объект Label, содержащий все свойства, поскольку они всегда различаются (зависит от HTML-кода шаблона, который должен быть заполнен этим запросом. Моя служба выполняет «поиск и замену» на основе имен свойств тега.
Я уже пробовал это: Как разобрать строку JSON в JsonNode в Джексоне?
Но я не могу добавить пустой массив к объекту JsonNode, как предполагалось.
Кто-нибудь может мне помочь?
С уважением,
Али




Итак, в основном то, что у вас есть в коде, таково:
final String jsonString = "[]";
Но в вашем запросе от почтальона вы отправляете labels как тип Array, а не как String.
Поскольку здесь не так много информации, можете ли вы проверить это тело:
{
"templateId":"5b1140608134691d1804e74e",
"labels":"[]"
}
И поделитесь выводом, или даже это (разница в типах) может помочь вам понять неожиданное поведение, с которым вы сталкиваетесь при попытке преобразовать массив в тип String. В тестовом классе вы должны попытаться получить JsonNode из arrayType
String[] labels in test class
ОБНОВИТЬ:
При использовании String [] вместо String для этикеток вам также необходимо указать тип прохода при получении JsonNode из String [].
Обратитесь к этой ссылке, чтобы узнать, как это сделать..
Я уже пытался вставить его в JSONArray вместо JsonNode по прибытии в PostLabelDTO, но, похоже, он не может его проанализировать, и я получаю сообщение об ошибке, что его неправильный синтаксис
Итак, конструктор всегда ожидает JsonNode? И когда вы отправляете запрос от почтальона, он сопоставляется с PostLabelDto, но не с вашим тестовым классом? Верный?
Да, он проходит не через тестовый класс, а через обычный маршрут (@JsonProperty и т. д.)
Я добавил пример (рабочий, заполненный запрос) в свой пост, чтобы вы его увидели, может, это поможет.
Можете ли вы проверить, является ли ваш ярлык jsonNode arrayNode методом .isArray (). В идеале это должен быть arrayNode.
Просто преобразуйте строковые метки в String [] в тестовом классе, чтобы преобразовать в JsonNode. Это может помочь
Я преобразовал private String jsonString = "[]" в String[] с String labels[] = jsonString.split("") ;, но получаю эту ошибку, а затем Error:(45, 65) java: incompatible types: java.lang.String[] cannot be converted to com.fasterxml.jackson.databind.JsonNode
Вам может потребоваться передать тип при получении массива или попробовать что-нибудь отсюда: stackoverflow.com/questions/16788213/… По сути, вам просто нужно получить JsonNode из массива String
Это сработало как шарм, спасибо !!! Обновите свой ответ, чтобы я мог выбрать его как лучший!
Попробуйте использовать labels как String[] в PostLabelDTO
public class PostLabelDTO {
private final String templateId;
private final String[] labels;
public String[] getLabels() {
return labels;
}
@JsonCreator
public PostLabelDTO(final @JsonProperty("templateId") String templateId,
final @JsonProperty("labels") String[] labels) {
this.templateId = templateId;
this.labels = labels;
}
public String getId() {
return templateId;
}
}
Затем проверьте этот код, как показано ниже:
String str[] = {};
PostLabelDTO postLabelDTO = new PostLabelDTO("fj2j931j2ijd1", str);
Для вашего фактического запроса с этим большим JSON у вас должен быть PostLabelDTO, как показано ниже
public class PostLabelDTO {
@JsonProperty("templateId")
private String templateId;
@JsonProperty("labels")
private List<Label> labels = null;
....
}
Попробуйте сгенерировать POJO из JSON с помощью ссылки jsonschema2pojo, он сгенерирует правильные классы JAVA, и вы можете протестировать работу с помощью этого вызова, используя фактическое тело запроса JSON.
Мне нужно получить строку JSON для использования в других функциях. Так что в идеале getLabels вернет чистый JSON вместо массива.
Я получаю эту ошибку { "timestamp": "2018-06-01T17:24:07.706+0000", "status": 400, "error": "Bad Request", "message": "JSON parse error: Cannot deserialize instance of java.lang.String из токена START_OBJECT; вложенное исключение - com.fasterxml.jackson.databind.exc.MismatchedInputException: невозможно десериализовать экземпляр java.lang.String из токена START_OBJECT \ n в [Источник: (PushbackInputStream); строка: 3, столбец: 12] (через цепочку ссылок: han.oose.margriet.dto.PostLabelDTO [\ "labels \"] -> java.lang.Ob ject [] [0]) "," путь ": "/ label /"} `
где вы получаете эту ошибку в вашем методе getEmptyDocumentException()?
У меня есть метод, который выдает это исключение, когда в «метках» есть пустой массив, а не заполненный, как вы можете видеть в моих двух примерах в моем OP.
Здравствуйте, что касается вашего комментария о создании POJO для этого. Макет метки может быть динамическим, поэтому может быть больше или меньше полей со списком заказов и т. д. И т. Д.
Я думал, что у вас есть максимальное количество полей, которые могут входить в метку, а затем создать POJO с этими полями, если все или меньше поступают, тогда хорошо, но если появится какой-то узел, которого нет в вашем POJO, тогда он не будет работать.
Нет нет максимальных полей, он полностью динамический. Таким образом, метка может иметь либо 5 полей, либо, возможно, 100, в зависимости от шаблона, который заказчик сделал для заполнения (например, просто HTML-код с <div id = "price"></div>, который заполняется свойством "цена" из JSON-запроса, например).
Это дает мне
{ "timestamp": "2018-06-01T16:50:53.377+0000", "status": 500, "error": "Internal Server Error", "message": "A JSONArray text must start with '[' at 1 [character 2 line 1]", "path": "/labels/" }