Hello all I am having trouble understanding the b...
# general
n
Hello all I am having trouble understanding the benefits of handling provider asynchronous tests as unit tests instead of treating them as component level tests like the the synchronous provider tests. Let me elaborate: For the provider sync tests I am currently spinning up a docker container with the provider service and I set the provider state by writing records to a database and by simulating HTTP interactions and Kafka interactions with other downstream services. For provider async tests I can just as easily set the state by writing records to the database and simulate downstream interactions with the other services. And when it comes to verifying the message all I need to do is pull the message from the topic (I am using Kafka) and pass it on to Pact. I already have tooling in place to spin up the provider as a docker container for the synchronous tests so it is straight forward to use it for the asynchronous tests — and in my case the same provider has both asynchronous and synchronous interactions sometimes with the same consumer.
t
I think the primary benefit is that you don't have to spin up the provider in a container with all of its machinery. If this is not a cost for you, your way sounds fine
n
Thank you 🙌
t
There's a side point here, though - it sounds like you might be writing directly to your database during setup - I don't think this is a good idea, as it ties your database implementation into your tests
I personally usually mock that whole layer with something that fulfils the same interface
n
Do you do that even for asynchronous tests ?
t
like, say my database access comes through a class with the signature
getUser(id)
, which returns a
User
or throws
NotFound
, then I would mock that class
yes
The reason writing to the DB as part of the test setup can be painful is - what if you change your DB format?
then you have to update the test
but the test isn't about that format
knowing the format is incidental
this is one of the reasons that a unit test setup can be superior - you might (quite reasonably) say "well, I want to test with my real database"
so, we could initialise an empty database, and then in the unit test setup we could call the
saveUser(someUser)
method on the DB access class (for example)
I like the rule that a test will fail if - and only if - the interface or the behaviour change
I don't think the data in the database is part of the interface
Your test will still work if it knows the database structure, I'm just flagging that I think it will be harder to maintain
n
The database structure is not likely to change (in fact it is more likely the interface will change at this stage of development). I though the purpose of spinning up the entire provider as part of the provider verification was to ensure you are actually verifying a real provider message (or response in case of sync).
t
Yes, that's right. The idea is that it's always the real code - but a consumer test can do that without spinning up the whole thing. However, the current implementation of message pacts doesn't include the sending and receiving of messages, which is why spinning up the whole thing isn't the norm. You could, but you may need to build a small test runner to fire the messages
n
As part of the provider test I fetch the messages from the kafka topic and send them to Pact.