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 480 forks source link

Contract test example for message queue in clojure #1099

Open neharastogi093 opened 4 years ago

neharastogi093 commented 4 years ago

Could you please point me to some example for writing message queue pact tests. If clojure examples are not possible then java example will also work.

I am having trouble finding equivalent of ConsumerPactRunner/runConsumerTest which excepts the MessagePact instead of RequestResponsePact.

Example for both consumer and producer would help.

uglyog commented 4 years ago

Oh, wow! Clojure still around! :-D

There are no examples that I know of. In fact, this is the first time I've heard of someone trying to do message queue Pact tests with Clojure.

The main issue with message queue tests is they invoke a method to either generate the message (on the provider side) or process the message (on the consumer side). The JUnit examples use annotated methods for this.

So there are a few options:

  1. Write your clojure tests as JUnit tests using annotations (I assume you can do this).

  2. Create a test that is similar to https://github.com/DiUS/pact-jvm/blob/master/consumer/junit/src/test/clojure/au/com/dius/pact/consumer/junit/example_clojure_consumer_pact_test.clj, which would need a support method similar to ConsumerPactRunnerKt/runConsumerTest but that deals with messages. No mock server will be started.

  3. Write the test support method in Clojure.

neharastogi093 commented 4 years ago

Hi @uglyog - I prefer the second option. Do you think you can accommodate this in near future? Thank in advance.

chrisport commented 4 years ago

Hi @uglyog I've attempted to implement the required helper method (your suggested option 2), which could be used by a Clojure test to run a test and write the json file. Happy about any feedback! Pull request

uglyog commented 4 years ago

Can you write you Clojure test now? If you could contribute an example test for the project, it would be helpful for other people.

dpunna-ut commented 2 months ago

Can you write you Clojure test now? If you could contribute an example test for the project, it would be helpful for other people.

Hi @uglyog I have tried the clojure provider verification using dependency [au.com.dius.pact/provider "4.6.14"] And here is the test verification, not sure if this is how we setup, can someone give some examples if it is working?

(ns insights.contract.provider-state-verification-search-test
  (:require [clojure.test :refer :all]
            [insights.events.kafka.producer :as producer]
            [insights.events.kafka.schemas :as kafka.schemas]
            [jsonista.core :as json]
            [insights.api.handlers.reports :refer [create-new]]
            [malli.generator :as mg])
  (:import [au.com.dius.pact.provider ProviderVerifier]))
  ;; (:import [au.com.dius.pact.consumer ConsumerPactBuilder ConsumerPactRunnerKt PactTestRun PactVerificationResult$Ok]
  ;;          [au.com.dius.pact.provider ProviderVerifier]
  ;;          [au.com.dius.pact.consumer.model MockProviderConfig]))

(defn setup-report-created-state []
  ;; Define the mock database and event producer
  (let [mock-db (atom {})
        mock-produce-event! (fn [event] (println "Event produced:" event))
        parameters {:body {:title "Sample Report" :content "Sample content"}}
        utz-context {:account_uuid "account-123"
                     :workspace_uuid "workspace-123"
                     :user_uuid "user-123"}
        event {:type "com.insights_hub.report.created"
               :data (mg/generate kafka.schemas/report-created)}]

    #_(create-new {:db mock-db :produce-event! mock-produce-event!}
                  {:parameters parameters :utz-context utz-context})
    (println "Setup for report-created state completed.")
    event))

(defn handle-provider-state [state-name]
  (cond
    (= state-name "the report created") (setup-report-created-state)
    ;; Add additional conditions for other states here
    :else (println (str "No setup for state: " state-name))))

(def pact-verification-config
  {:provider "insights-hub-service"
   :pact-urls ["insights/test/insights/contract/search-insights-hub_reportCreated.json"]
   :state-change-fn handle-provider-state
   :state-change-teardown (fn [] (println "Tear down after state change"))})

(deftest verify-report-created-pact
  (au.com.dius.pact.provider/verify-pacts pact-verification-config))

Error

lein test insights.contract.provider-state-verification-search-test
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
2024-09-19 14:01:23,164 [insights.main] TRACE:   - {}
2024-09-19 14:01:27,101 [insights.main] INFO :  duration="4225016334" log/message="ENGINE ON!" version="SNAPSHOT" - {}
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
2024-09-19 14:01:28,521 [insights.main] TRACE:   - {}
2024-09-19 14:01:32,115 [insights.main] INFO :  duration="3842553833" log/message="ENGINE ON!" version="SNAPSHOT" - {}
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Syntax error (ClassNotFoundException) compiling at (insights/contract/provider_state_verification_search_test.clj:42:3).
au.com.dius.pact.provider

Full report at:
/var/folders/j6/n8t9vp3x1_dbf7njv71cps5h0000gq/T/clojure-4093100563818879263.edn
Subprocess failed (exit code: 1)

Can someone help here please

YOU54F commented 1 month ago

Hey @dpunna-ut

We have an existing kafka springboot example provider

https://github.com/pactflow/example-provider-java-kafka

I am very new to clojure. Is there any change you could create a simple example repo, maybe modelled on the above. I can see you are using kafka in your example code.

Maybe that way we can provide both an example for clojure, and then have the ability to have a codebase to test against, to improve the lien plugin to support message providers.

YOU54F commented 1 month ago

So I took a look at this example project

https://github.com/uglyog/pact-lein-test

and noted that I am unable to publish verification results when verifying a pact by url, and I can't seem to retrieve via a PactBrokerSource with consumer version selectors using the lein plugin.

the verifying pact by url issue not publishing results, is also raised here

There is an example of a consumer test using junit annotations. an example on the consumer side is here

https://github.com/pact-foundation/pact-jvm/blob/v4.1.x/consumer/junit/src/test/clojure/au/com/dius/pact/consumer/junit/example_clojure_consumer_pact_test.clj

I wonder if you can work backwards from a message pact provider example in junit

https://github.com/pact-foundation/pact-jvm/blob/46ae177cdab2dfa09608998afa92a13b6b0a0656/consumer/junit/src/test/java/au/com/dius/pact/consumer/junit/v3/PactVerificationsForHttpAndMessageTest.java#L67

as currently it looks like you would need to extend the current lein plugin for a few features for it to be suitable (pact broker source, publish verification results, add message pact support)