Hacker News new | ask | show | jobs
by cultofthecow 1101 days ago
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 you're testing - its a bit weird and smelly. Consider rethink SOLID principles at least.

4. Go. Gen. Effectively you can automate mock generation. Debatable but it's cool.

Just. Keep. Things. Simple. Depend on what you need. Mock behaviour you need. Try to test flattened structure - do not test the layer below the one you're testing ATM (unit tests).

2 comments

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.

how come mocks make you tightly coupled with implementation?

Use and depend on abstractions maybe?

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).

what does it mean “mocked out hashtable”?

Whole hashtable? Or what?

You mock interface/api of “something” you depend on to model the behavior you might deal with within the part of code you test.

thats it. nothing else.

during unit test phase I want to make sure that this exact code works as a state machine given all the possible inputs/outputs and that it handles any possible situation any dependency can cause.

If you need to debug code BECAUSE of the tests and not WITH the tests then something is wrong with the architecture or approach.

tldr. mock dependencies. model behavior of the dependencies. make sure you can debug the code with the help of your unit tests on the very layer you’re working with at the moment.

I find that mock-heavy tests I've interacted with are low ROI: they don't find or predict bugs, require significant work to write, and often have to be updated when the code under test has changed even when the actual feature/case being tested has not changed.

While mocks can be useful, IMO "never use mocks" isn't a terrible rule of thumb.