Isolating with spies ;TLDR
Read ⚡️ Stubs first.
A spy or a mock is a function that records the interactions our application has with it. In Jest, a mock function becomes a spy when we use a toHaveBeenCalled
or toHaveBeenCalledWith
matcher.
.toHaveBeenCalled()
- expect a mock function to have been called as part of the test.
.toHaveBeenCalledWith(arg1, arg2)
- expect a mock function to have been called with one or more arguments as part of the test.
Let's look at an example:
In the above example, assume that our test
is part of the test suite for VendingMachine
. We don't want to pass a real Snack
object into our VendingMachine
's purchaseSnack
method, as this wouldn't be an isolated test, so instead we stub snack
, ensuring the interface matches that of our Snack
prototype/constructor. When our stub does get passed into purchaseSnack
, the addSale
method gets called, which in this case is our spy. The assertion below expect(snack.addSale).toBeCalled()
therefore passes, as the addSale
method was called.
Challenge
We have a problem in our Ship
test suite currently in that 3 tests directly test the Port
object:
Refactor these tests so that they incorporate spies.
To complete this challenge, you will need to:
Note many of the changes below will happen in the beforeEach
function callback. You will need to use the matcher toHaveBeenCalledWith
.
- In
can set sail
you will need to remove the assertion onport.ships
and instead assert thatship.setSail
callsport.removeShip
(whereport
is a stub, andremoveShip
is a method on that stub). - In
gets added to port on instantiation
you will need to remove the assertion onport.ships
and instead assert thatport.addShip
has been called (again,addShip
will be a spy on aport
stub). - In
can dock at a different port
you will need to remove the assertion oncalais.ships
and instead assert thatcalais.addShip
has been called withship
(again,addShip
will be a spy on aport
stub).