Live data from Hacker News

Prefer Fakes over Mocks

tyrrrz.me

101–110 of 125 posts

Re: Prefer Fakes over Mocks

#101
I have been researching into several testing approaches and so far in my experience yes fakes are better than mocks. But what is even better is not having to fake or mock stuff especially for testing business logic.

One of the problems we get ourselves into is abstracting service io code into functions and calling them from our business logic code. This forces us to mock all the io calls, instead we should be doing the opposite i.e abstracting business logic into discrete functions of pure data in and out and then calling those functions from our io code. This way we can test the business logic independently of the io code. Testing the business logic now becomes quite simple and one can leverage property testing to further boost our confidence in such tests.

Many times the ramaining io code is just calling other functions and doesn't need to be tested.

Several other ideas that relate to this are hexagonal architecture, Domain Driver Design, clean architecture and functional core with an imperative shell.

Some resources to further explore these ideas:

Clean Architecture in Python - https://youtu.be/DJtef410XaM

Why integrated tests are a scam - https://youtu.be/VDfX44fZoMc

Boundaries - https://youtu.be/yTkzNHF6rMs

Re: Prefer Fakes over Mocks

#102
post #37
post #5

Earlier quoted context omitted.

I tried to distill down the basics a few years ago in a 1 page article: https://testing.googleblog.com/2013/06/testing-on-toilet-fak... The example is a little contrived, but the whole article fits on one sheet of paper and does yield a better test than mocks would. Testing against the real system is always better than testing against a fake. That should be your first preference, and if you can modify the system to m…

> if you can modify the system to make testing against it easier, that's even better. What do you mean here? Changing your testing system, or changing the real system?

Changing the real system to add the hooks you need. Complexity often exists around waiting for events to happen (the real system doesn't need notifications, but you don't want your tests to run forever when they're failing), clocks (time.Now() is difficult to test), things like that.

Re: Prefer Fakes over Mocks

#103
post #17

Earlier quoted context omitted.

Because they don't just implement a part of the interface (just one store method, or just one of two load methods). They try to create a fully functional fake of the original class. In this case instead of storing the blobs via a REST interface or a database connection, it just keeps it in memory. So it should mostly behave like the real implementation, but is not suitable for production, as it doesn't persist the da…

> Because they don't just implement a part of the interface (just one store method, or just one of two load methods). They try to create a fully functional fake of the original class. So shouldn't fakes have their own tests as well? Mocks don't need tests (at least in C# with a framework) because no new class is ever written. Anyway most of these issues are inherently linked to the nature of OOP and are a direct trad…

On the best scenario, your fakes just replace some standard components your have on production with other standard components, and keep everything else equal. On those cases, no they don't need tests. But when you are doing something weirder, they pretty much do.

On the best scenario, your mocks are just data that doesn't have timing characteristics, don't react to the system being tested, and are short enough to not need any kind of compression (in loops or gzip). On those cases, they don't need tests. But if you are doing anything weirder, they pretty much do.

I honestly don't see any sense in separating them in categories like if they had discreete non-overlapping mono-dimensional properties.

Anyway, why do you claim any of that is specific to OOP?

Re: Prefer Fakes over Mocks

#104
post #96

Even more important, IMO, regardless of whether you're mocking or faking, is to not mock or fake objects that you own. Only mock/fake truly external dependencies. The nice property you get with this is true tests of integration and interoperability between your modules, that are actually calling into each other. Only at the leaf nodes is anything mocked or faked, and that's when it leaves your ownership.

While I 100% agree with you on this point, you should take a few minutes and read this: https://medium.com/@adrianbooth/test-driven-development-wars... It's a fantastic comparison of the Detroit school of testing (what you and I believe) vs the London school, which is simply a different mental model about code and testing and mocks especially. Framing the differences this way make it clearer why some people might dis…

Nice framework for thinking about it, thanks. Totally agree.

For me, the biggest benefit is that I want to be able to refactor the internals of my code and have the tests (which map to business requirements, not implementation details) still pass.

It's also because a lot of the code I work with is inherently concurrent, and in my estimation, you're getting a lot more test coverage with the detroit model because a lot of your threading cases are simply covered if you use real objects and test it black-box style.

Re: Prefer Fakes over Mocks

#105
post #96

Even more important, IMO, regardless of whether you're mocking or faking, is to not mock or fake objects that you own. Only mock/fake truly external dependencies. The nice property you get with this is true tests of integration and interoperability between your modules, that are actually calling into each other. Only at the leaf nodes is anything mocked or faked, and that's when it leaves your ownership.

While I 100% agree with you on this point, you should take a few minutes and read this: https://medium.com/@adrianbooth/test-driven-development-wars... It's a fantastic comparison of the Detroit school of testing (what you and I believe) vs the London school, which is simply a different mental model about code and testing and mocks especially. Framing the differences this way make it clearer why some people might dis…

What if I like outside-in, black-box testing

Because I like to test everything, not just little parts I isolate?

Re: Prefer Fakes over Mocks

#106
post #71

Even more important, IMO, regardless of whether you're mocking or faking, is to not mock or fake objects that you own. Only mock/fake truly external dependencies. The nice property you get with this is true tests of integration and interoperability between your modules, that are actually calling into each other. Only at the leaf nodes is anything mocked or faked, and that's when it leaves your ownership.

Mocks for your own code, fakes for external dependencies but in both cases only where you can’t rework your most of your code to consume the outputs of dependencies instead of soliciting them. Fixtures trump mocks and fakes. Having multiple tests fail for the same reason is a waste of effort, either now or in the future (when new features are added or the constraints otherwise change). Sometimes you have to depend on…

Why would you mock your own code, when you have your own real code right there?

Re: Prefer Fakes over Mocks

#107
post #25

Earlier quoted context omitted.

The article addresses this: you need to write tests for the fake as well. I'm not sure I buy this as something that's desirable to have to do, but it should address your concern.

Hmm, if I’m having to write tests for my tests, I feel something has gone wrong in my life ;)

A fake is an implementation. The same tests you use on the real implementation also test the fake implementation.

Re: Prefer Fakes over Mocks

#108

I don't think he really sells the point to me. You can use any tool incorrectly. An application with poor composition conmbined with mocks without verifications leads you down the path he describes. What we should do is only use "mocks to create fakes", which if you read the manuals on Mockito, is what they're pushing you towards anyway. So in conclusion I would say that a lot of people use mocking frameworks incorre…

You only use mocks to create fakes if you are stuck with mocks and you are learning along with the Mockito authors that fakes are better.

Re: Prefer Fakes over Mocks

#109

I'm a little surprised this article and none of the contents here at the time of this writing mentioned inheritance. The core reason I find OOP to be superior for most classes of business application development in general—and web development in particular—is that external dependencies and other high cost interfaces can be delegated to their own method or instance variable then called. In general, I avoid inheritance…

Inheritance is orthogonal. The stuff you want to override can just as well be composed in instead, as a constructor paramter.

Re: Prefer Fakes over Mocks

#110
post #33

How are fakes, as described in this article, not also implementation-aware testing?

The fake is coupled to the "real" implementation of the interface. But the test that uses the fake is no longer coupled to the implementation of the fake/mock. Instead of counting how many times a method is called (mock), your test just gets to test the outcome of the overall operation (fake).

> counting how many times

That's an expectation which is an extra optional layer on top of mocking. The important difference between mock and fake is that a separate mock has to be created for every single test, but a fake needs only be created once for all tests that use the faked dependency.

Post reply on HN