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

Move filtering aspect out of JUnit Runners #572

Closed thombergs closed 6 years ago

thombergs commented 7 years ago

Currently, the only way to have a provider test not run against all interactions of a Pact is to use @RunWith(FilteredPactRunner.class) in combination with @PactFilter.

This poses a problem if you want to use a different PactRunner like RestPactRunner or SpringRestPactRunner in combination with filtering.

Probably the most user-friendly way is to make all PactRunners support filtering and have them process the @PactFilter annotation. This way, the @PactFilter annotation would work from the user's perspective regardless of which runner is used.

uglyog commented 7 years ago

Good idea! That makes a lot of sense.

uglyog commented 7 years ago

Done.

thombergs commented 6 years ago

Awesome. Is there a snapshot version or something like that so I can test the feature?

nikitasharma2692 commented 6 years ago

When the code will be published on Maven

uglyog commented 6 years ago

3.5.9 has been released

thombergs commented 6 years ago

I cannot get @PactFilter get to work together with @SpringRestPactRunner.

I have the following pact:

{
  "consumer": {
    "name": "ui"
  },
  "provider": {
    "name": "userservice"
  },
  "interactions": [
    {
      "description": "a request to POST a person",
      "providerState": "provider accepts a new person",
      "request": {
        "method": "POST",
        "path": "/user-service/users",
        "headers": {
          "Content-Type": "application/json"
        },
        "body": {
          "firstName": "Arthur",
          "lastName": "Dent"
        }
      },
      "response": {
        "status": 201,
        "headers": {
          "Content-Type": "application/json"
        },
        "body": {
          "id": 42
        },
        "matchingRules": {
          "$.body": {
            "match": "type"
          }
        }
      }
    },
    {
      "description": "a request to PUT a person",
      "providerState": "person 42 exists",
      "request": {
        "method": "PUT",
        "path": "/user-service/users/42",
        "headers": {
          "Content-Type": "application/json"
        },
        "body": {
          "firstName": "Zaphod",
          "lastName": "Beeblebrox"
        }
      },
      "response": {
        "status": 200,
        "headers": {
        },
        "body": {
        }
      }
    }
  ],
  "metadata": {
    "pactSpecification": {
      "version": "2.0.0"
    }
  }
}

This is my provider Test with Spring Boot:

@RunWith(SpringRestPactRunner.class)
@Provider("userservice")
@PactFolder("../pact-angular/pacts")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, properties = {
        "server.port=8080"
})
@PactFilter({"provider accepts a new person"})
public class UserControllerProviderTest {

    @MockBean
    private UserRepository userRepository;

    @TestTarget
    public final Target target = new HttpTarget(8080);

    @State("provider accepts a new person")
    public void toCreatePersonState() {
        User user = new User();
        user.setId(42L);
        user.setFirstName("Arthur");
        user.setLastName("Dent");
        when(userRepository.save(any(User.class))).thenReturn(user);
    }

}

My expectation would be that the test runs successfully, since the @PactFilter only contains the provider state "provider accepts a new person". Instead it fails with this error:

MissingStateChangeMethod: Did not find a test class method annotated with @State("person 42 exists")

although the provider state "person 42 exists" should be filtered out.

uglyog commented 6 years ago

Ok, let me have a look. Sounds like the states are evaluated before the interactions are filtered.

uglyog commented 6 years ago

The filtering should work now with the SpringRestPactRunner

thombergs commented 6 years ago

Checked again with 3.5.13. I'm still getting the same error.

schuettec commented 6 years ago

Is there any progress on this one?

uglyog commented 6 years ago

I did implement a fix for this, but @thombergs has indicated that it is still not working. I need more information on how it is still not working to proceed.

thombergs commented 6 years ago

Re-tested this and it works in 3.5.16 :).