Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Mocks have their uses, but overzealous overmocking really means the death of a test suite. At this point, tests become more of a nuisance than anything helpful (especially in a statically typed language where you know that if your code compiles the pieces at least sort of have to fit together).

Mocks (or related techniques such as stubs, fakes) are useful when you have to interact with an outside system (e.g. send emails), for testing boundary conditions that are hard to replicate (what happens if an error is thrown), for highly generic code or, potentially, for really major architectural boundaries in your code base (but I feel that most people overestimate the confidence they have that they've determined the correct boundaries).

For anything else, I'd prefer to isolate pure code from code with side effects as much as possible so that the former can be unit tested without any dependencies (even if one class/module/whatever calls another, it doesn't have to be mocked out), and the latter is mostly just wiring that can be tested through a combination of integration testing and maybe some occasional use of a mock here and there.

Unfortunately not many code bases are structured that way, so you'll have to pick your battles and maybe live with more (brittle) mocks than you'd like - or with slower and more flakey (integration) tests that you'd like.



I have an extremely hard time reading & benefitting from tests that make use of excessive mocks. Some apps I've worked on recently have mocked out so many things, large parts of the code base don't actually get hit by the actual tests. It's super annoying. To be honest I can't even make sense of it most of the time.


I felt that. But also : how do you deal with testing interaction with an external API. Or code that you control but require a large effort to instanciate? ( you want to test f but need to standup a,b,c,d and e. I find it tempting to mock e and call it a day.


I think it's fine to mock out a call to an external service (e.g. your app making calls to AWS S3). But when you mock out too many calls to code in your own app, that's brittle in my opinion. For example, say your testing the "Foo.new.().foo()" method, and you mock out calls to "Bar.new().bar()". You could make a breaking change in "Bar.new().bar()", say you go from returning "bar" to "BAR". The test in "Foo.new.().foo()" would keep passing while testing the wrong value. Now if you do that all over your application, you can have a nicely factored test suite that is completely detached from reality.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: