Skip to content

Instantly share code, notes, and snippets.

@s-espinosa
Last active August 20, 2017 16:57
Show Gist options
  • Save s-espinosa/5d3f1b14ecfaa6a83af8855a37f23dbd to your computer and use it in GitHub Desktop.
Save s-espinosa/5d3f1b14ecfaa6a83af8855a37f23dbd to your computer and use it in GitHub Desktop.

If we had infinite resources, we wouldn't bother stubbing methods out. Stubbing adds a layer of complexity to our tests.

However, our machines have limited computing power. Tests that touch multiple objects (even in the background), or read and write files, or perform complex calcuations take longer to run than tests that touch a single object/method.

When tests take too long to run, developers stop running tests.

Tests are no good to us if we don't run them.

We have to make tests run quickly for them to maintain their value.

In order to make our tests run quickly, we try to test things (especially expensive things) only when we need to, and only once.

So, if we have a complex calculation, we want to test it directly once to make sure it works. If that test fails, we know our calculation is broken.

However, if we have multiple other objects that use the output of that complex calculation, and we test those other objects, and they call the complex calculation, then that slows our tests unnecessarily.

We don't need to test that calculation indirectly if we've tested it directly.

You can substitute File/IO (including querying our database) for the complex calculation above. These are also things we try to avoid when possible.

Because of this we prefer unit tests to integration tests.

A unit test is not truly a unit test if it reaches out to collaborators (e.g. our complex calculation); that's an integration test.

Stubs provide a way for us to test methods without testing/calling their collaborators. This help keep our unit tests fast.

Instead of performing that complicated calculation (which is tested elsewhere), just assume that it's working and that it sends me back what I expect. Then test that when the method I'm trying to test (the system under test) receives the result, it does what we want it to do.

This leads to an interesting corollary: if the collaborating method that you're calling isn't slow, maybe you don't bother stubbing it out. This is where there seems to be more disagreement in the community based on how dogmatic people are about isolating their unit tests.

More resources below if you'd like to dig further into the arguments/tools of how to write good, efficient tests.

Sometimes the question of how much to mock/stub is framed as a difference between classicist and mockist schools of testing, which some of the links below address.

I'm not as familiar, but believe that the majority of this has root in Extreme Programming. Many of the concepts there should feel familiar based on Turing's approach.

Videos

Definitions

Best Practices

What Not to Do

Alternative Viewpoints

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment