Open AnhTaFP opened 1 year ago
Thanks for the detailed report.
This is likely a limitation of the JSON parser. It seems somewhere in the chain 5.0 is being reduced to simply 5.
Can you confirm that what is sent over the wire is 5 or 5.0? In JS I know it will be 5 even if a decimal is provided. As such there's not much a test framework can do if it doesn't receive a value with decimal places.
I think you're right, I wrote another small program to check the ouput of the json marshaller in Go in this case
package main
import (
"encoding/json"
"log"
"net/http"
)
func main() {
type product struct {
ID int `json:"id"`
Price float64 `json:"price"`
}
http.HandleFunc("/products/1", func(writer http.ResponseWriter, request *http.Request) {
d := product{
ID: 1,
Price: 5.0,
}
b, _ := json.Marshal(d)
log.Println("product is marshalled into", string(b))
writer.Header().Set("Content-Type", "application/json")
writer.Write(b)
})
http.ListenAndServe("localhost:8080", nil)
}
I called the end-point, and here's the log
2023/08/06 09:54:38 product is marshalled into {"id":1,"price":5}
It looks like the json marshaller in Go truncates 5.0
to 5
, so the behavior is the same as JS. I don't know how to overcome this for now (except writing my own marshaller), maybe just make sure that the provider verifier tests avoiding decimal with only 0
after the decimal point.
Software versions
go env
Expected behaviour
5.0
should be a valid decimal value when running provider verifierActual behaviour
5.0
is not considered a valid decimal value when running provider verifierSteps to reproduce
consumer
and its test.import ( "encoding/json" "fmt" "io" "net/http" )
type ProductConsumer struct { host string }
func NewProductConsumer(host string) *ProductConsumer { return &ProductConsumer{ host: host, } }
func (c ProductConsumer) GetProduct(id int) (Product, error) { url := fmt.Sprintf("%s/products/%d", c.host, id) resp, err := http.DefaultClient.Get(url) if err != nil { return nil, err } defer resp.Body.Close()
}
type Product struct { ID int
json:"id"
Price float64json:"price"
}Run the test, get the output of the pact
Create a provider test
import ( "encoding/json" "net/http" "testing"
)
func startServer() { type product struct { ID int
json:"id"
Price float64json:"price"
}}
func TestProductProvider(t *testing.T) { go startServer()
}
=== RUN TestProductProvider 2023-08-05T14:11:11.107350Z INFO ThreadId(11) pact_verifier: Running setup provider state change handler 'product #1 exists' for 'a request to get product #1' 2023/08/05 21:11:11 [INFO] executing state handler middleware 2023-08-05T14:11:11.287108Z INFO ThreadId(11) pact_verifier: Running provider verification for 'a request to get product #1' 2023-08-05T14:11:11.287166Z INFO ThreadId(11) pact_verifier::provider_client: Sending request to provider at http://localhost:52872/ 2023-08-05T14:11:11.287168Z INFO ThreadId(11) pact_verifier::provider_client: Sending request HTTP Request ( method: GET, path: /products/1, query: None, headers: None, body: Missing ) 2023-08-05T14:11:11.288802Z INFO ThreadId(11) pact_verifier::provider_client: Received response: HTTP Response ( status: 200, headers: Some({"content-length": ["18"], "content-type": ["application/json"], "date": ["Sat, 05 Aug 2023 14:11:11 GMT"]}), body: Present(18 bytes, application/json) ) 2023-08-05T14:11:11.288821Z INFO ThreadId(11) pact_matching: comparing to expected response: HTTP Response ( status: 200, headers: Some({"Content-Type": ["application/json"]}), body: Present(18 bytes, application/json) ) 2023-08-05T14:11:11.290069Z INFO ThreadId(11) pact_verifier: Running teardown provider state change handler 'product #1 exists' for 'a request to get product #1' 2023/08/05 21:11:11 [INFO] executing state handler middleware
Verifying a pact between product-consumer and product-provider
a request to get product #1 (0s loading, 522ms verification) Given product #1 exists returns a response which has status code 200 (OK) includes headers "Content-Type" with value "application/json" (OK) has a matching body (FAILED)
Failures:
1) Verifying a pact between product-consumer and product-provider Given product #1 exists - a request to get product #1 1.1) has a matching body $.price -> Expected '5' to be a decimal value
There were 1 pact failures
--- FAIL: TestProductProvider (0.58s) === RUN TestProductProvider/Provider_pact_verification verifier.go:184: the verifier failed to successfully verify the pacts, this indicates an issue with the provider API --- FAIL: TestProductProvider/Provider_pact_verification (0.00s)
FAIL
Process finished with the exit code 1