Describe the bug
First of all, thank you for your great work about Microcks !
I am playing around with it to replace PACT testing that does not suit our needs.
I am trying to execute contract tests as defined in this example : https://github.com/microcks/microcks-testcontainers-java#launching-new-contract-tests and some of the operations required technical headers.
Therefore I have setup my test like this :
@Test
void validate_open_api_contract() throws Exception {
Header header1= new Header();
header1.setName("my-required-header-1");
header1.setValues("value-1");
Header header2 = new Header();
header2 .setName("my-required-header-2");
header2 .setValues("value-2");
TestRequest testRequest = new TestRequest.Builder()
.serviceId("some-api:1.0")
.runnerType(TestRunnerType.OPEN_API_SCHEMA.name())
.testEndpoint("http://host.testcontainers.internal:" + port + "/path")
.filteredOperations(List.of("GET /resources}"))
.operationsHeaders(Map.of("GET /resources", List.of(header1, header2)))
.build();
TestResult testResult = microcks.testEndpoint(testRequest);
ObjectMapper mapper = new ObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL);
System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(testResult));
assertThat(testResult.isSuccess()).isTrue();
}
When I execute, I got a org.testcontainers.shaded.com.fasterxml.jackson.databind.JsonMappingException
due to headers.
I am using io.github.microcks:microcks-testcontainers
version 0.1.3
.
Expected behavior
I expect the deserialization of the response to a TestResult
works.
Actual behavior
When Microcks tries to deserialize the response to a TestResult
, I got the following exception :
org.testcontainers.shaded.com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_ARRAY token
at [Source: {"id":"651ea7baa485fb277f71cddb","version":0,"testNumber":1,"testDate":1696507834409,"testedEndpoint":"http://host.testcontainers.internal:33907/path","serviceId":"651ea7b9a485fb277f71cdd2","timeout":10000,"elapsedTime":0,"success":false,"inProgress":true,"runnerType":"OPEN_API_SCHEMA","operationsHeaders":{"GET /resources}":[{"name":"my-required-header-1","values":["value-1"]},{"name":"my-required-header-2","values":["value-2"]}]},"testCaseResults":[{"success":false,"elapsedTime":-1,"operationName":"GET /resources}","testStepResults":[]}]}; line: 1, column: 380] (through reference chain: io.github.microcks.testcontainers.model.TestResult["operationsHeaders"]->io.github.microcks.testcontainers.model.OperationsHeaders["GET /resources}"]->java.util.HashSet[0]->io.github.microcks.testcontainers.model.Header["values"])
at org.testcontainers.shaded.com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:270)
at org.testcontainers.shaded.com.fasterxml.jackson.databind.DeserializationContext.reportMappingException(DeserializationContext.java:1234)
at org.testcontainers.shaded.com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1122)
at org.testcontainers.shaded.com.fasterxml.jackson.databind.deser.std.StringDeserializer._deserializeFromArray(StringDeserializer.java:91)
at org.testcontainers.shaded.com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:41)
at org.testcontainers.shaded.com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:11)
at org.testcontainers.shaded.com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:504)
at org.testcontainers.shaded.com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:104)
at org.testcontainers.shaded.com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:276)
at org.testcontainers.shaded.com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:140)
at org.testcontainers.shaded.com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:287)
at org.testcontainers.shaded.com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:259)
at org.testcontainers.shaded.com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:26)
at org.testcontainers.shaded.com.fasterxml.jackson.databind.deser.std.MapDeserializer._readAndBindStringKeyMap(MapDeserializer.java:517)
at org.testcontainers.shaded.com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:362)
at org.testcontainers.shaded.com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:27)
at org.testcontainers.shaded.com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:504)
at org.testcontainers.shaded.com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:104)
at org.testcontainers.shaded.com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:276)
at org.testcontainers.shaded.com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:140)
at org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3798)
at org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2842)
at io.github.microcks.testcontainers.MicrocksContainer.testEndpoint(MicrocksContainer.java:203)
at io.github.microcks.testcontainers.MicrocksContainer.testEndpoint(MicrocksContainer.java:165)
This is because, the mapper tries to deserialize the array ["value-2"]
to the field values
: https://github.com/microcks/microcks-testcontainers-java/blob/main/src/main/java/io/github/microcks/testcontainers/model/Header.java#L42 which is a String
.
As a quick workaround, I have created a custom deserializer but I though that Jackson was able to handle it by default...
package io.github.microcks.testcontainers.model;
import org.testcontainers.shaded.com.fasterxml.jackson.core.JsonParser;
import org.testcontainers.shaded.com.fasterxml.jackson.core.JsonProcessingException;
import org.testcontainers.shaded.com.fasterxml.jackson.core.JsonToken;
import org.testcontainers.shaded.com.fasterxml.jackson.databind.DeserializationContext;
import org.testcontainers.shaded.com.fasterxml.jackson.databind.JsonDeserializer;
import org.testcontainers.shaded.com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class Header {
private String name;
private String values;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValues() {
return values;
}
@JsonDeserialize(using = ArrayToStringDeserializer.class)
public void setValues(String values) {
this.values = values;
}
}
class ArrayToStringDeserializer extends JsonDeserializer<String> {
@Override
public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
if (jsonParser.currentToken() == JsonToken.START_ARRAY) {
List<String> values = new ArrayList<>();
jsonParser.nextToken();
while (jsonParser.hasCurrentToken() && jsonParser.currentToken() != JsonToken.END_ARRAY) {
values.add(jsonParser.getValueAsString());
jsonParser.nextToken();
}
return String.join(",", values);
}
return null;
}
}
How to Reproduce?
No response
Microcks version or git rev
No response
Install method (docker-compose
, helm chart
, operator
, docker-desktop extension
,...)
No response
Additional information
No response