Live data from Hacker News

Don't Use Mocks

joeblu.com

51–60 of 85 posts

Re: Don't Use Mocks

#51
post #19

Can we not have articles like this with blanket statements like this please? As with everything in software, no one size fits all. Mocks have their place. There are situations when the only way we can test something out is to mock out a certain function call. Sometimes our dependencies are so complex and deep that we cannot just replace it with a fake. But with a little mock we can replace a function or a class withi…

I don't grasp the difference between a mock and a fake. Both are substitutes for an expensive or unavailable component. Maybe the fake is more dynamic than the mock? The point seems moot.

I actually agree. I think the point the author is trying to make it that fake can be reused in more places and stay relatively same as the code updates.

But I personally think that instead of spending the time to write a fake, its better to just spend the time writing actual integration test with the real dependency (eg: just run the db in docker or something)

or if you don't want to spend that time, then just record the interaction (eg: db calls) and create "throwaway stubs". Use this stubs as long as they are relevant, and then generate new ones as your code grows. Save time "writing" any mocks, and you don't tend to couple too much with your mocks :P

Re: Don't Use Mocks

#52

There are entirely separate communities IMO when it comes to automated tests. There are the pushing-the-edge-of-excellence folks, constantly refining methods and approaches, who tend to be passionate about the holistic benefits of testing. And there are the folks who write convoluted tests that, when you dig into them, just confirm that String's .equals() works OK. DAO/database tests which have mocking going on to th…

I cannot count the number of python and perl tests leveraging mocks that we inherited that after we dug into them, there tests were asserting that 1=1 exactly as you say. "Make the db return hello, insure we returned hello; yay, framework works?". Unit tests should validate error paths are properly exercised and that we handle expected results appropriately. It is wild how often this is not expressed in unit tests.

On the other hand, I've been surprised just how often a simple "1=1 in a roundabout way" sanity test explodes in my face. The code people write is just that shit. And so is, often, my understanding of it. So I always like to keep around tests confirming we can shuffle some data back and forth on the "golden path" - they're good documentation, good at detecting broken refactors, ad well... if you're going to point out that a test effectively checks if String.equals() works OK - sure, but that's an implementation detail, to which the test is oblivious, and you should be too.

Re: Don't Use Mocks

#53

Earlier quoted context omitted.

https://github.com/rr/rr

"Currently RR implements mocks, stubs, proxies, and spies. Fakes usually require custom code, so it is beyond the scope of RR."

Ah yes - I'm getting confused between fakes and stubs.

Either way, RR is good to have in the toolbox.

Re: Don't Use Mocks

#54
post #17
post #5

Nah I'm about done working on rails codebases with 2+ hour CI cycles because developers insist on hammering a database in unit tests.

I can see a two-tier approach working. First run tests with mocks that runs very quickly, because no DB or API calls are made, they are mocked. Then run a full-on test that includes DB calls, because this will fully test your app better than mocks ever could. This way if a mocked test fails you find out much faster.

This is my take. I have one test suite that should be able to run upon file-save and be completed in about 5 seconds. Then another suite that takes about 20 minutes that I can run in CI or locally. I suppose unit vs integration, but I don't worry about conforming to those definitions too strongly. Basically tests in the first suite should be fast and able to run in parallel. If they touch the file system or talk to a local db that's fine as long as it's fast and safe in parallel. The second suite can do whatever.

Re: Don't Use Mocks

#55

Such a bad take IMHO. Sorry. 1. You still need to update the fake object once you gonna add a new behaviour. 2. Fake object has a tendency to become logic heavy. Someone will add a stupid-not-needed-map to test some shit you don't need to test in this unit\layer. 3. You only need to mock the behaviour you depend on. If you've added new Method and you need to mock it despite the fact you're not using it in the code yo…

Mocks force you to be aware of how your method/function under testing operates at a low level. At that point your test is now tightly coupled to a specific implementation. YMMV, but I can safely say from working on large codebases across several companies I've seen this get painful at scale when things change, whether it's a simple refactoring or an optimization pass. Mocks also tend to be much, much more complicated on a per test basis.

All that said, I personally prefer the upfront investment in stubs. At scale, it is something readily reusable by other test suites and teams out there.

Re: Don't Use Mocks

#56

Such a bad take IMHO. Sorry. 1. You still need to update the fake object once you gonna add a new behaviour. 2. Fake object has a tendency to become logic heavy. Someone will add a stupid-not-needed-map to test some shit you don't need to test in this unit\layer. 3. You only need to mock the behaviour you depend on. If you've added new Method and you need to mock it despite the fact you're not using it in the code yo…

I once worked with a mockist who mocked out hashtable. It didn't end well when we had to debug his code.

I once knew a mockist who mocked out all the external code's behavior, but didn't add tests to ensure that the external code behaved as they expected.

That didn't end well either.

Just don't use mocks, unless they're the simplest thing that could work (usually not).

Re: Don't Use Mocks

#57
post #19

Can we not have articles like this with blanket statements like this please? As with everything in software, no one size fits all. Mocks have their place. There are situations when the only way we can test something out is to mock out a certain function call. Sometimes our dependencies are so complex and deep that we cannot just replace it with a fake. But with a little mock we can replace a function or a class withi…

I don't grasp the difference between a mock and a fake. Both are substitutes for an expensive or unavailable component. Maybe the fake is more dynamic than the mock? The point seems moot.

What he calls a fake is what I call a mock - although I don't think he's necessarily building a strawman here, there are developers who use mocks the way he's telling you not to, and they are creating the problems that he outlines. I'd change it from "don't use mocks" to "don't be stupid with mocks".

Re: Don't Use Mocks

#58

Earlier quoted context omitted.

I don't grasp the difference between a mock and a fake. Both are substitutes for an expensive or unavailable component. Maybe the fake is more dynamic than the mock? The point seems moot.

I actually agree. I think the point the author is trying to make it that fake can be reused in more places and stay relatively same as the code updates. But I personally think that instead of spending the time to write a fake, its better to just spend the time writing actual integration test with the real dependency (eg: just run the db in docker or something) or if you don't want to spend that time, then just record…

> just run the db in docker

That creates unit tests that take ages to run - and fail surprisingly in hard to debug ways.

Re: Don't Use Mocks

#59
post #26

The point is: if your tests just assert which methods are called on dependencies with what arguments (or something close to that), they are extremely coupled and brittle. Almost any change in the implementation will require changing such tests. And by their nature, they probably test some minor low-level things, that are not all that valuable to assert anyway. Mocks enable and encourage this kind of testing. Better t…

The tests you propose might take 10x longer to run. There is value in having quick tests as a first level of validation.

Mocks are tracking and storing behaviour and almost always are doing much more than fakes (which globalreset proposes) which are just simple (and ideally, correct) implementations.

Re: Don't Use Mocks

#60
post #19

Can we not have articles like this with blanket statements like this please? As with everything in software, no one size fits all. Mocks have their place. There are situations when the only way we can test something out is to mock out a certain function call. Sometimes our dependencies are so complex and deep that we cannot just replace it with a fake. But with a little mock we can replace a function or a class withi…

Sure, the title is clickbait. But the message seemed useful: if your test rigidly requires every call be made in exactly the way it is made now, then your test will be brittle. For a less brittle test, re-implement the functionality in a simpler form.

What this article did not do was to describe the trade-off: what you give up by creating a more complicated "fake" (to use the author's term).

Post reply on HN