HTML and CSS Reference
In-Depth Information
16.7 Mocks or Stubs?
The comparison of stubs and mocks raises the question, stubs or mocks? Unfortu-
nately, there is no answer, other than “it depends.” Stubs are more versatile; they can
be used simply to silence dependencies, fill in for not-yet-implemented interfaces,
force a certain path through the system, and more. Stubs also support both state
verification and behavior verification. Mocks can be used in most scenarios as well,
but only support behavior verification.
Although mocks can also be used to silence dependencies, doing so is somewhat
unpractical because we must take care to set up the expectations to account for
the minimum amount of possible calls, for example by using expectation.
atLeast(0) .
Wrapping tests in sinon.test and using mocks definitely yields the fewest
lines of test code. When using stubs, assertions are required, something the implicit
mock verification deals away with. However, as assertions go away, tests may also
end up less clear and intent revealing.
The upfront expectations used by mocks break the convention that the verifica-
tion stage is always carried out last. When mocks are involved, we need to scan the
entire test for verification code. The problem can be mitigated by keeping mock ex-
pectations at the top of the test, but there is still a possibility that further verification
is carried out in assertions in the bottom of the test.
Although the choice between stubs and mocks is mainly one of personal pref-
erence and project convention, there are cases in which you definitely should not
use mocks. Because mocks implicitly perform behavior verification that can break
the test—both during the test and after—mocks should never be casually used to
fake interfaces that are not the focus of a given test.
As an example of unsuitable use of mocks, consider Listing 16.24, which shows
an excerpt of the chat client's form controller handleSubmit test case. The setUp
creates an inline model object whose publish method is a stub. Not all tests
interact with this object, but it is required by the controller, which is why it's fed to
the controller in the setUp method.
Listing 16.24 A stub that should not be made into a mock
setUp: function () {
/* ... */
this.controller = Object.create(messageController);
this.model = { publish: stubFn() };
/* ... */
Search WWH ::

Custom Search