J'ai donc deux projets de démarrage Spring. Dans le projet A, j'appelle le contrôleur du projet B via une classe de service pour récupérer une ResponseEntity contenant une liste de chaînes. La classe de service du projet A étant le consommateur et B étant le fournisseur dans la terminologie du Pacte:Pacte: non HttpMessageConverter trouvé pour le type de réponse
BookServiceInterfaceImpl.java
@Service("bookService")
public class BookServiceInterfaceImpl implements BookServiceInterface {
public ResponseEntity<List<String>> getBookTitlesForCourse(final String courseId){
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String[]> response = restTemplate.getForEntity("http://localhost:8888/api/book/course/" + courseId, String[].class);
List<String> titles = Arrays.asList(response.getBody());
return new ResponseEntity<List<String>>(titles, HttpStatus.OK);
}
}
BookController.java
@RestController
@RequestMapping("/api")
public class BookController {
private BookService bookService;
@Autowired
public BookController(BookService bookService) {
this.bookService = bookService;
}
@RequestMapping(method = RequestMethod.GET, value="/book/course/{id}")
public ResponseEntity<String[]>getBookTitlesForCourse(@PathVariable("id") final long id) {
List<Book> books = bookService.findAllBooks();
if(books.isEmpty()) {
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
String[] bookTitles = books.stream()
.filter(book -> book.getCourseId() == id)
.map(book -> book.getTitle())
.toArray(String[]::new);
return new ResponseEntity<String[]>(bookTitles, HttpStatus.OK);
}
}
Je suis en train d'utiliser Pacte pour créer un contrat entre les deux. Jusqu'à maintenant, je le test suivant chez le consommateur:
BookServiceTest.java
@RunWith(SpringRunner.class)
@SpringBootTest
public class BookServiceTest {
@Rule
public PactProviderRuleMk2 mockProvider = new PactProviderRuleMk2("test_provider", "localhost", 8080, this);
@Pact(provider="test_provider", consumer="test_consumer")
public RequestResponsePact createPact(PactDslWithProvider builder) {
return builder
.given("test state")
.uponReceiving("BookServiceTest test interaction")
.path("/api/book/course/1")
.method("GET")
.willRespondWith()
.status(200)
.body("{[\"Dont make me think\",\"Clean Code\"]}")
.toPact();
}
@Test
@PactVerification("test_provider")
public void test_retrieveBooksForcourse_validCourseId_success() {
//given
final String courseId = "1";
BookServiceInterfaceImpl bookService = new BookServiceInterfaceImpl();
//when
ResponseEntity<List<String>> response = bookService.getBookTitlesForCourse(courseId);
//then:
assertThat(response.getStatusCode(), is(200));
assertThat(response.getBody().size(), is(2));
}
}
Et le fichier pom pour le consommateur est:
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ocr</groupId>
<artifactId>new-consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>new-consumer</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.6.RELEASE</version>
<relativePath />
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>au.com.dius</groupId>
<artifactId>pact-jvm-consumer-junit_2.11</artifactId>
<version>3.5.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Quand je lance, je reçois le texte suivant:
java.lang.AssertionError: Pact Test function failed with an exception: Could not extract response: no suitable HttpMessageConverter found for response type [class [Ljava.lang.String;] and content type [application/octet-stream]
at au.com.dius.pact.consumer.BaseProviderRule.validateResult(BaseProviderRule.java:164)
at au.com.dius.pact.consumer.BaseProviderRule$1.evaluate(BaseProviderRule.java:77)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [class [Ljava.lang.String;] and content type [application/octet-stream]
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:110)
at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:917)
at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:901)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:655)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:613)
at org.springframework.web.client.RestTemplate.getForEntity(RestTemplate.java:312)
at com.ocr.newconsumer.service.BookServiceInterfaceImpl.getBookTitlesForCourse(BookServiceInterfaceImpl.java:29)
at com.ocr.newconsumer.controller.BookServiceTest.test_retrieveBooksForcourse_validCourseId_success(BookServiceTest.java:60)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at au.com.dius.pact.consumer.BaseProviderRule.lambda$runPactTest$1(BaseProviderRule.java:150)
at au.com.dius.pact.consumer.BaseMockServer.runAndWritePact(MockHttpServer.kt:152)
at au.com.dius.pact.consumer.ConsumerPactRunnerKt.runConsumerTest(ConsumerPactRunner.kt:13)
at au.com.dius.pact.consumer.BaseProviderRule.runPactTest(BaseProviderRule.java:148)
at au.com.dius.pact.consumer.BaseProviderRule.access$100(BaseProviderRule.java:21)
at au.com.dius.pact.consumer.BaseProviderRule$1.evaluate(BaseProviderRule.java:76)
... 20 more
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at au.com.dius.pact.consumer.BaseProviderRule.lambda$runPactTest$1(BaseProviderRule.java:150)
at au.com.dius.pact.consumer.BaseMockServer.runAndWritePact(MockHttpServer.kt:152)
at au.com.dius.pact.consumer.ConsumerPactRunnerKt.runConsumerTest(ConsumerPactRunner.kt:13)
at au.com.dius.pact.consumer.BaseProviderRule.runPactTest(BaseProviderRule.java:148)
at au.com.dius.pact.consumer.BaseProviderRule.access$100(BaseProviderRule.java:21)
at au.com.dius.pact.consumer.BaseProviderRule$1.evaluate(BaseProviderRule.java:76)
... 20 more
Je ne suis pas exactement ce que la question est, de ce que je sais que je suis sûr que ce genre de conversion ne doit pas être une grande chose et devrait être manipulé par Spring. Y a-t-il quelque chose que je fais de façon incorrecte en ce qui concerne l'appel REST ou le test (la première fois en utilisant Pact)? Ai-je manqué une dépendance dans le pom que j'ai supposé que les parent/dépendances de Spring Start auraient?
donc je pense que vous dites que je devrais modifier mon code d'implémentation pour l'adapter à une bibliothèque de test, alors que la bibliothèque de test ne devrait pas faire le travail ici, malgré tout, je vais essayer cette approche quoi que ce soit autour de surcharger runTest dans l'exemple sur github im en utilisant comme référence: https://github.com/DiUS/pact-jvm/blob/master/pact-jvm-consumer-junit/src/test/java/au/com/ dius/pact/consumer/examples/ArticlesTest.java – jbailie1991
Ok, j'ai implémenté le changement et modifié le test pour ressembler à l'exemple affiché. Je reçois toujours la même erreur HttpMessageConverter alors ne pense pas que c'est le problème – jbailie1991
Ah bon point. J'ai déjà vu cette erreur et j'ai toujours trouvé un moyen de contourner le problème. Avez-vous vu cette? https://stackoverflow.com/a/21857557/1490322 –