5 ms·
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
by distcs 3y ago
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 within that dependency to decouple our tests from it.
Having a title with a blanket statement like "Don't Use Mocks" is either plain wrong or clickbait. In this case, it seems it is both wrong and clickbait. Such blanket statements and clickbaits specifically trigger people to get into a long-winded debate (ironically, my own comment here is a case in point) about something that is obvious and otherwise uncontroversial.
- smitty1e 3y agoI 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.
- sethammons 3y agoMaybe more eloquently put: https://martinfowler.com/articles/mocksArentStubs.html https://martinfowler.com/articles/mocksArentStubs.html
- TeMPOraL 3y agoMocks, fakes, stubs. Every time I read this article I end up more confused than I was before.
- Ma8ee 3y agoI like Uncle Bob’s explanation: https://blog.cleancoder.com/uncle-bob/2014/05/14/TheLittleMocker.html https://blog.cleancoder.com/uncle-bob/2014/05/14/TheLittleMo...
- sethammons 3y agoThat is a solid way to introduce the different test doubles. Thanks for the link. I agree, stubs and spies are my daily bread. I also use fakes very regularly. I hardly ever use mocks, for the same reasons in the post.
- john-radio 3y agoAs a Python main I'm wondering if the difference has to do with a strictly typed language like the author's two examples, Go and Java, requiring more boilerplate and interface classes and so on, that in turn require more customization of the mock (since he writes that it "implements the API of what it replaces" which seems like it would be a strange thing to say about a python mock).
- eximius 3y agoA fake is a 'local' or lower fidelity implementation of the real thing. A array/memory backed DB instead of postgres, etc. A mock is a cache for a desired return value (which is hopefully what the real interface would correctly return). Edit: actually sethammons link is great
- oslac 3y agoMock has expectations about how the function is called. If you read a file from a disk, and you expect it only to be done once, a mock is "usable" in this scenario to count the number of invocations. Note that there aren't outside, observable, state changes or behavior involved in this. It is about the non-functional introspection. Fake is just a simple implementation, like in-memory db to stand-in for a real one. In the optimal case, provided by library authors.
- slayerjain 3y agoI 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
- zackees 3y agoIf running a micro service use sqlalchemy and switch your db to sqlite for testing purposes. There are scalability limits to this but for most cases it works extremely well and is fast.
- commandlinefan 3y ago> just run the db in docker That creates unit tests that take ages to run - and fail surprisingly in hard to debug ways.
- commandlinefan 3y agoWhat 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".
- arp242 3y agoHow I understand it: A mock is a set of fixed data; sometimes people even load these from YAML documents and the like. They're often re-used for different tests. A fake is a "fake" object created when needed, with the parameters you need. Mock: user = load_user_mock() article = load_article_mock() run_test(user, article) Fake: user = newUser(Name: "foo", Email: "foo@example.com") # Or generate random data article = newArticle(User: user, Title: "bar") run_test(user, article) The difference is somewhat subtle, but I often find mocks very inconvenient because you can't "just" change one without lots of stuff falling over. It's also much harder to do something "special" with them for that one test.
- xcdzvyn 3y agoThank you. Seeing this on page 1 is just sad.
- mcherm 3y agoSure, 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).
- Maxion 3y agoA naive question here, should I not then in a unit test, test that an API library is called with specific arguments? I am confused, wouldn't using simpler and "broader" tests miss test coverage on e.g. specific error handlers?
- boringuser2 3y agoActually, I feel that making strong statements of opinion regarding code style is probably the best way to go about doing things.