Fakes, spies, stubs & mocks
I learned how to test code using Jest. Today I’m working on a codebase that doesn’t have Jest and I have to use Jasmine and Sinon instead.
The most confusing bit is going through the documentation and trying to understand what fakes, spies, stubs, and mocks are. In Jest, I just dealt with mocks. I thought everything was a mock.
I’ve learned that all of these things fall under the umbrella of test doubles. I think I’ve figured out what the difference between each type of test double is now…
Spies - Listen #
So a spy is when you just listen to the implementation of a dependency. You run the original function, but you just want to test whether it was run, how many times it was run, and what parameters it was run with.
Mocks - Bypass #
A mock is when you bypass a function altogether. If you have a dependency that’s coupled to your code that does important stuff but is unrelated to what you’re testing, you can mock the dependencies out so it won’t get fired.
For example, let’s say you’re testing a chunk of code that fires a bunch of analytics tracking requests. It’s important that it does that for real, but you don’t want to pollute your analytics database when you’re testing. Mocking the analytics calls lets you make sure they were called without having to actually call them.
Stubs - Override #
A stub is when you override a function entirely. Let’s say you’re testing payments in your app and you need to know that someone was charged x amount. Firing off the function for reals means you have to charge yourself $5 every time you run the test. Now, you can’t just mock the function because it’s important that you get a response from the payment provider to complete the test. This is where you would use a stub to override the function altogether and simulate the response your need to do your test.
I haven’t figured out what Fakes are yet. I think they are when you write a simplified version of a function and use that for testing instead. So, for example, if you have a complicated function that hits a database and generates a user ID, you could just use a much simpler, fake ID generator function in its place.
But then wouldn’t that just mean it’s a stub? So I’m still a bit confused about fakes, but I think I’ve figured the other ones out.
Part of the problem here is that the definitions around this stuff are really loose online and different people and libraries have different words for things.
If you can help further clarify this at all , please let me know on Twitter at @joshpitzalis