6.5. Architecture considerations for effective mocking/stubbing

This chapter closes with some theory that isn’t strictly specific to Spock, but is essential to effective unit tests that contain mocks and stubs.

6.5.1. Designing testable code that allows painless mocking

If after reading the examples in this chapter, you get the feeling that I was always lucky that collaborator classes were so easily mocked and stubbed, you’re half correct. One of the prerequisites of easy mocking is to have written your source code in a testable manner. By that I mean

  • Code that’s injected with its dependencies (inversion of control)
  • No static classes/global state
  • No static fields
  • No singletons
  • No complex constructors
  • No service locators and hidden dependencies

Spock (and any other testing framework, for that matter) can’t help you if the production code isn’t in a usable state. It helps to follow the test-driven-development paradigm when you create Spock tests.

Also note that for Java production code, Spock can’t mock static methods and/or private methods on its own. This is done by design.[12] Even though this might seem like a limitation, you should see it as a motivation for writing testable code. For more information, consult Test Driven by Lasse Koskela (Manning, 2007). The book talks about JUnit, but the advice it gives on testable Java code also applies to Spock.

12

Mockito also does not support mocking of static/private methods.

If you really, really want to mock static/private methods, you need to use a framework such as PowerMock (https://code.google.com/p/powermock/). You might already have experience with it because Mockito also doesn’t support mocking of private methods and needs PowerMock for this purpose. I don’t like the PowerMock solution (it uses a custom class loader and bytecode manipulation) and would use it only as a last resort. Spock can be used together[13] with PowerMock via the PowerMockRule JUnit rule (https://code.google.com/p/powermock/wiki/PowerMockRule).

13

6.5.2. Understanding lenient vs. strict mocks

The underscore character is powerful in Spock, and as you’ve seen, it can be used on a wide range of elements, from single arguments to full classes. But as with all things in software engineering, a trade-off exists between strict tests (which explicitly specify all interactions and arguments) and lenient tests (which rely heavily on the underscore character and the default stubbing behavior of Spock).

Strict tests catch subtle bugs, but in the long run are hard to maintain, because even the slightest change in external interfaces or business requirements will make them break. Even adding a single method to a class that’s used in a mock will instantly break any test that uses the 0 * _ line as a last statement.

On the other hand, lenient tests won’t break often, but may miss some hard-to-reproduce bugs that occur because of corner cases and strange combinations of arguments.

My advice is to use strict tests for the mission-critical parts of your application and lenient tests for everything else. Following the Pareto principle, about 20% of your tests should be strict and the rest (80%) should be lenient. As always, this suggestion should only be a starting point for your own application and business needs.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.50.222