How to implement the "or()" method in dius.pact

Viewed 520

i am writing a pact test and I need a variability.

this is my actual method for defining an price object:

private static LambdaDslObject definePrice(LambdaDslObject object) {
  return object
      .stringType("type") // <--- could be empty or has 2 different values
      .stringType("currencyCode", "EUR")
      .numberType("centAmount")
      .numberType("fractionDigits");
}

but this price object could look like this in JSON:

if type is "centPrecision" or empty:

"value": {
  "type": "centPrecision",
  "currencyCode": "EUR",
  "preciseAmount": 2800,
  "fractionDigits": 2 // <--- is not mandatory in this case
}
or
"value": {
  "currencyCode": "EUR",
  "preciseAmount": 2800,
  "fractionDigits": 2 // <--- is not mandatory in this case
}

or if type is "highPrecision"

"value": {
  "type": "highPrecision",
  "currencyCode": "EUR",
  "centAmount": 2800, // <--- is not mandatory in this case
  "preciseAmount": 2800,
  "fractionDigits": 2
}

so I need a distinction according to type of the price.
I found this or() method but actually don't know how to implement it.
how can I implement this for pact?

1 Answers

In this case, I would write two Pact tests, and use provider state to tell the provider which one to produce.

Rationale

Each individual pact test has a number of fixtures. We'll call them P, X, Y, Z and O. These fixtures are used to make the following assertions:

  1. When the consumer code is called with some parameters P
  2. Then request X is sent to the provider
  3. When the provider is in state Y, it produces response Z
  4. When the consumer receives response Z, domain object O is returned to the caller from step 1.

If you have an or in your test, you have two different values of Z. In turn, you'll have two different values of O, and either two different values of X and P or two different values of Y (or both), depending on whether the type in Z changes based on the request or not.

Let's say the response in Z changes based on the provider state (the simpler case). If you use or, your test will now look like this

  1. When the consumer code is called with some parameters P
  2. Then request X is sent to the provider
  3. When the provider is in state Y-1, it produces response Z-1, or if it is in state Y-2 it produces response Z-2
  4. When the consumer receives response Z-1, domain object O-1 is returned to the caller from step 1, or if the consumer receives response Z-2, domain object O-2 is returned to the caller.

This is significantly more complex than splitting in to two tests.

The two tests

Test one could be something like:

  1. When the consumer code is called with (whatever parameters)
  2. A request for a LambdaDslObject is sent
  3. When the provider state is response is centPrecision, it produces:
    "value": {
      "type": "centPrecision",
      "currencyCode": "EUR",
      "preciseAmount": 2800,
      "fractionDigits": 2 // <--- is not mandatory in this case
    }
  1. Which returns an appropriate domain object to the caller.

And test two could be something like:

  1. When the consumer code is called with (whatever parameters)
  2. A request for a LambdaDslObject is sent
  3. When the provider state is response is highPrecision, it produces:
    "value": {
      "type": "highPrecision",
      "currencyCode": "EUR",
      "centAmount": 2800, // <--- is not mandatory in this case
      "preciseAmount": 2800,
      "fractionDigits": 2
    }

As an aside, remember that your Pact test should describe only the response fields the consumer actually uses - it's not intended as a full description of the fields returned from the provider. So, you may be able remove the non-mandatory fields from the response.

Related