Hey everyone, I'd like to find/conclude the best p...
# pact-jvm
a
Hey everyone, I'd like to find/conclude the best practices regarding mocking on the provider side. Once I participated in a Pact meetup and I heard (from Matt I think) that it's recommended not to mock layers but prepare the state around the service, i.e. inserting into the database etc. Which I support very much. Though I still see that people are mocking mostly for the reason that writing a mock on the controller level seems easy. As well I see that in the PactJVM workshop there is a recommendation/example to mock results returned by the repository layer. Q: Do we have somewhere a community conclusion regarding this? If not, let's conclude and I can list my points if it's needed. Just my point is mocking evil and as soon folks start writing this they copy-paste the approach.
t
I personally believe it’s best to mock at the repository layer.
I’ve written this up a bit somewhere, let’s see if it’s still in slack.
Hm. It isn’t.
In quick points - If you mock at the controller, you only know that the service might produce the response you want, not that it actually does in at least one case If you insert into the database, your state setup knows too much about the database structure (which will be a pain to maintain, and you have the reverse problem, where you don’t know if that data ever gets in to the database). If you mock at the repository layer, then your mock is simple as it is expressed in domain concepts
when "user '10' exists" then repo.getUser('10') returns {....}
etc, robust to implementation changes of the repository layer, and also those mocks can be used to check the contract tests for that layer too.
I think the argument for mocking at the controller is so that you don’t start driving functional tests with your contract tests. I agree that functional tests shouldn’t be driven by your contract tests (this is also a maintenance issue, where the consumer knows too much about the provider’s behaviour), but I think it’s an advantage if your contract tests have some functional coverage, where they would fail if that specific behaviour broke. This is the main point I made in the video
👍 1
m
yep, what Tim Said
I think I remember you from the TestJS Summit maybe? In any case, hello! 👋
So yes, I would suggest mocking at the repository layer also. It’s a good default for most teams. If you mock elsewhere, that’s totally acceptable, but comes with more caveats - the main one is ensuring you have the testing coverage elsewhere in your code and that all of these tests are properly aligned, otherwise you can end up in a situation where you have mocked the controller, but haven’t considered the actual scenarios downstream of it, and there are gaps.
👍 1
a
Thanks, everyone, I think I participated in exactly that conference 🙂 Good to have that presentation reference, I will use that negotiating
My personal preference was preparing the database for every test by inserts. Because this way makes sure that the provider operates as it will be on any actual environment. This way our state is an example of a state that we could compare with an actual state in any environment. Tests look more isolated from the behavior and rely on the external state. Another personal argument is that I do not trust Java mocks, it makes us think about the Java classes rather than the pure data. Though I agree that mocking on the repository layer looks good to move away from the database structure dependency. I see a good reason here that usually there are fewer converters between the repository layer and the actual database data. If we would have many converters than it would be difficult to match the mock data with the actual database data troubleshooting and using contract tests as an example.
t
How do you know that what you are inserting in the database looks like what you will really have in a real environment?