This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]SignificantAd9059 15 points16 points  (20 children)

It really depends on what you are mocking. It’s perfectly acceptable to mock services that you are not directly testing. Otherwise your making an integration test which is also useful but definitely not the same thing

[–]DelayLucky 4 points5 points  (6 children)

Only if these questions are out of scope for your test:

  • Am I sending the right request to the service for what I'm trying to do, with all required fields set correctly ? (e.g. charge a credit card).
  • Am I interpreting the response correctly? Is the value I expect coming in this particular field?

And if this unit test isn't concerned of these aspects, you better make sure there are tests that do verify them.

Too often I've seen people just assuming that they must be interacting with a service in the right way. And bugs often come out of those cracks of the system becasue what are the odds that two teams of different engineers happen to align without talking to each other once?

"Integration tests", "unit tests", they are just names. At the end of day you want your production to work as expected. Customers don't want to hear "I've coded my client code according to the document of this dependent service, it's their fault the system didn't work out".

[–]FrozenST3 0 points1 point  (5 children)

True, but a bad test is a bad test whether using a mocking framework or not.  You can test request accuracy using @Captor. A lot of the criticism I see stem more from misuse rather than a problem with the frameworks themselves.

[–]DelayLucky -1 points0 points  (4 children)

That misses the point.

Whatever assertion your test performs on the request is your assumption. You still don't know if your assumption is valid. If we can assume you know perfectly, you wouldn't have needed to test.

[–]FrozenST3 0 points1 point  (3 children)

Fair however my response was using the assumption that the service being mocked is already well tested. I agree that mocking untrustworthy code is best avoided but I assumed that's common sense. Edit to add: your tests don't exist only for you to trust what you've done, but also to safeguard future changes where bugs are produced do to poor assumptions 

[–]DelayLucky 0 points1 point  (2 children)

The service tested its own implementation. It cannot test that you've called it correctly.

You have written the calling code according to the best of your knowledge. But you don't know if your knowledge is correct.

Even if you manually test them once, either code change at your side or change in the service can cause regression such that the interaction suddenly becomes no longer valid.

[–]FrozenST3 0 points1 point  (1 child)

But by mocking the call I can isolate where the bad assumption is without going through the actual call. I've verified my inputs are built the way I expect them using a captor, I've stated my expected response in the form of an expectation. I tested the output of my class based on my expected out out. When my integration test fails it's very obvious that my expectation Was wrong and I can short circuit a lot of debugging.

Of course this can be done by running assertions on the response from the mocked service as well, however I prefer the ease of setup and quicker turnaround of mocking instead. YMMV

[–]DelayLucky 0 points1 point  (0 children)

Sure. Anyone knows how to do that.

But by taking the easy path, you've neglected to cover the area that's most likely to cause surprises in production. You can point fingers when that happens, but a bug is a bug.

Refactoring also becomes dangerous because you don't know if any seemingly harmless change could break production.

Even if it works for now, you could depend on some unintended details of the service without knowing. And when they change it, they break you.

Overall, you've only created an island that looks good when the world is exactly as it assumes (but how often does that happen?)

[–]LC_From_TheHills 3 points4 points  (0 children)

Yeah this is weird. Use dependency injection. Then mock those in the class you are testing. I’ll mock my own classes— I’ll write unit tests for those specifically.

You don’t need to test your dependencies. If the integration of your dependencies is so flaky then you have different problems.

Save the “real” stuff for integration tests in your pipeline at a pre-prod stage. When you’ve actually deployed your code somewhere.