Hello, does anyone know (or have examples) if its ...
# general
t
Hello, does anyone know (or have examples) if its possible to have consumer tests generate pacts without using a
mockServer
and instead using something like
MockK
? I have tried but get
PactMismatchesException
saying the request was not received
I was looking at this example https://technology.lastminute.com/contract-testing-asynchronous-messaging-pact-junit-mockk/ but I cant get it working without using
mockServer
m
As a general rule, you need to hit the Pact mock server. Otherwise it complains it can’t be use that your code did what it said and can’t serialise a reliable contract. Not sure how the lastminute folks are using it, maybe they are just mocking out other parts of the method call? Also the lastminute example is a message based example, which doesn’t have a mock server in the same way the HTTP one does
t
Why would you want to do this?
PactMismatchesException
This means the mock server did not receive the request …. which isn’t surprising. The pact mock server is the thing that checks that your request looks like you said it would. It looks like the lastminute example is mocking out the repository layer of the service during pact verification - which is normal.
m
Yeah I think so too
What a lot of people want is a mocking experience like
MockK
but with the benefits of contract testing.
I understand that want, but we don’t have an ergonomic way of doing that right now.
t
What does MockK do that Pact doesn’t?
I guess I’m saying … I don’t understand the want 😅
m
For one, they don’t require the actual network call to be made.
That could be done of course
t
Oh, right - but, that doesn’t make sense
That could be done of course
🤔 …but then you lose the advantage of Pact, which is to check that you actually are sending the thing.
(or that you actually receive it)
m
Oh, right - but, that doesn’t make sense
Yes. Sort of. Obviously, the code should execute. In the sense that it needs to actually go through the whole network cycle is a separate thing. e.g.
nock
mocks the network layer and can do it in a way that’s pretty safe. The related thing is that you don’t need to configure your API client to point at the mock server, because the runtime can intercept it etc.
t
if you mocked the API of some underlying system (eg a popular HTTP client or whatever), then you’re back in mock land, and the answer stops being “yes, these two systems can communicate properly” and starts becoming “maaaaybe these two systems can communicate”
m
yes, it’s mostly a trade off of those guarantees, against ergonomics and speed
t
I don’t really see it being less ergonomic
I think it would be more ergonomic to write bad tests, which is not ideal
At the moment, yes, you have to be able to inject your API client’s configuration
but that just encourages good practice
m
Agree. I’m keen to hear from our actual customer (Thomas - sorry mate 😆 ), but the complaint that Pact tests are wordy and non-intuitive comes up a lot.
t
Thanks guys, interesting discussion. Yeah, I’ve only got it to work with
mockServer
for now, which is ok for our needs.
But the existing unit tests all just use
MockK
instead so thought it would’ve been nice if I can simply use
MockK
and still get the consumer expectations generated
t
I don’t think I understand the need
t
but using mockServer isnt too bad
t
for example, you wouldn’t say “these methods return strings, but the other tests are all using numerical assertions, so I was hoping we could use numerical assertions here too”
MockK and Pact are for testing different things
t
so it was more a question of using the two together instead of pact and mockServer
t
(Unless I am missing something, which is quite possible)
t
where u can mock the response without sending the network call to a mock server
t
As I understand it - MockK would let you assert on object method calls
whereas Pact lets you assert on actual http calls
….
right, but then you wouldn’t be testing the network calls?
Usually what I do is use (something like) mockK to test the API invocation, and Pact to test the actual API
that is, say there’s some method like:
api.getUser(userId)
I would do something like:
Copy code
val testUser = User(...some details here..)

api.getUser(1) <-- mock this to return testUser
^ I would do this for all the unit tests
then, in a Pact test, I would test that (when not mocked)
api.getUser(1)
fires the request that I am expecting, and I would confirm that the object that I get back is indeed the same as
testUser
t
thanks that makes sense, thats actually what we currently do for our unit tests and pact tests
🙌 1
so i guess ill keep it that way
👍 1
t
In this way, you can think of Pact as kind of a unit test for the API code
Where the “unit” is the pair of the client code and the network server code.
Ok, that’s good. We’re on the same page. What I’m confused about (and interested to understand ) is how it would be easier if you could write the pact tests with mocks
what would that look like?
t
So right now I have a separate pact test class to the unit test class mainly due to using slightly different things like mockServer etc
if it used
MockK
as we already have very similar unit tests, I would group it more with that
t
As an example, could you write up a pact test in the way that you’d like to use it? Like, just assume the API/DSL you want actually existed - I think that would be helpful for me to see what you’re getting at
t
sure can do later and will share here
t
So right now I have a separate pact test class to the unit test class mainly due to using slightly different things like mockServer etc
This sounds normal to me
👍 1
One nice way we could improve pact is to reduce the repetition - at the moment, there’s often a repeated request when there are several possible responses to an API call (there’s usually at least two for every call - one for success, and one for failure)
You can reduce some of that pain with nested tests, but I don’t know how well that would work with the JVM ecosystem
t
yeah we’re not a fan of nested tests really in JVM as it can get messy real quick
👍 1
t
https://gist.github.com/TimothyJones/d138bf765509d41e0ce8a4bfb777a31d You might be interested in this (although it is largely obsolete now, and also about Pact-JS) - it has some of the things we were thinking about when we made Jest-Pact to improve the boilerplate on the JS side
I agree. Every time I have tried it I’ve felt “this seems worse, but now I’m not keen to change it back”
Is the pain the DSL, the test time, or both?
t
the dsl and test time arent too bad to be fair, its more having to setup the retrofit interface to use the mockServer etc
id say its more a want than a need though to be honest
like everything is fine as it is now
t
Gotcha. That’s good news 😅
t
i kinda just saw that lastminute article and was like how?
😄
t
I’d be keen to see the hypothetical DSL if you get a chance though. In the worst case, it would generate an interesting discussion, and that’s a great worst-case
haha! Yeah. I think it’s a bit confusing. I think as Matt said, they’re doing: Pact verification -> Their service -> some mocks
t
sure will try to send something tonight, just woken up here in UK
🙌 1
t
but it’s confusing because in Pact Message, the “consumer test” is more like a verification
No rush at all
t
i see that kinda makes sense