pact-foundation / pact-jvm

JVM version of Pact. Enables consumer driven contract testing, providing a mock service and DSL for the consumer project, and interaction playback and verification for the service provider project.
https://docs.pact.io
Apache License 2.0
1.08k stars 479 forks source link

Support for @PactBroker etc. as Meta-Annotations in Spring #737

Open jhyot opened 6 years ago

jhyot commented 6 years ago

Modern idiomatic Spring code heavily uses and promotes the use of meta-annotations and composed annotations. See e.g. Spring Documentation and Spring Boot's testing meta-annotations like @WebMvcTest

I would like to make the Pact Junit provider annotations (like @Provider, @PactBroker etc.) meta-annotation-capable in Spring environments, so that I don't have to repeat the same annotations on every test class.

If you think this is worthwile, I could give it a try in a pull request.

Implementation Ideas:

The meta/composed annotations in Spring are possible because Spring has its own Annotation parser/helper classes which traverse the annotation graph. To support meta-annotations for pact I need to use these Spring utils. Because of the dependency to Spring the natural place to put the support would be in pact-jvm-provider-spring.

The annotation parsing code should be probably somewhere near or in SpringRestPactRunner.

Unfortunately, SpringRestPactRunner extends PactRunner where in the init block the checks for the annotations are currently performed. Maybe some way is needed to customize the annotation checking from subclasses. Not yet sure what's the best way.

API compatibility:

Apart from the possible constructor issue (see above), no API changes are necessary, because the Pact annotations would not be modified themselves. I only want to allow custom meta/composed annotations with the existing Pact annotations.

uglyog commented 6 years ago

The @Inherited annotation was added in #633 so they can be inherited. Or do you want to add them to some other annotation to include on your test classes?

jhyot commented 6 years ago

@Inherited only works if you include the annotation on a superclass. I am talking about the so-called "meta-annotations" where you annotate another annotation. Like here: https://www.logicbig.com/tutorials/spring-framework/spring-web-mvc/meta-annotation.html or here: https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTest.java

For this to work, the Spring annotation facilities must be used to scan/find annotations, as described in my initial post.