Test double is a pattern on unit testing. It replaces a test dependent component with an equivalent implementation that is specific to the test scenario.
These implementations are called doubles because although their behavior might be specific to the test, they act like and have the same API as the object they impersonate.
Spies are Jasmine's solution to test doubles.
At its core, a Jasmine Spy is a special type of function that records all interactions that happen with it. Therefore, they are very useful when a returned value or change in an object's state can't be used to determine if a test expectation was a success.
Or in other words, Jasmine Spies are perfect when a test success can only be determined by behavior checking.
To understand the concept of behavior checking, let's revisit an example presented in Chapter 3, Testing Frontend Code, and test the observable behavior of NewInvestmentView
:
describe("and when an investment is created", function() { var callbackSpy; var investment; beforeEach(function() { callbackSpy = jasmine.createSpy('callback'); view.onCreate(callbackSpy); investment = view.create(); }); it("should invoke the 'onCreate' callback with the investment",function() { expect(callbackSpy).toHaveBeenCalled(); expect(callbackSpy).toHaveBeenCalledWith(investment); }); });
During the spec setup, it creates a new Jasmine Spy using the jasmine.createSpy
function while passing a name for it (callback
), then it sets this spy as an observer of the View's create event using the onCreate
function, and finally it invokes the create
function to create a new investment.
Later on at the expectations, the spec uses the matcher's toHaveBeenCalled
and toHaveBeenCalledWith
to check if the callbackSpy
was called and with the right parameters (investment
), thereby making a behavior check.