Isolating with spies - Walkthrough
Steps
- In
can set sailyou will need to remove the assertion onport.shipsand instead assert thatship.setSailcallsport.removeShip(whereportis a stub, andremoveShipis a method on that stub). - In
gets added to port on instantiationyou will need to remove the assertion onport.shipsand instead assert thatport.addShiphas been called (again,addShipwill be a spy on aportstub). - In
can dock at a different portyou will need to remove the assertion oncalais.shipsand instead assert thatcalais.addShiphas been called withship(again,addShipwill be a spy on aportstub).
can set sail
First of all, we want to stop using Port and instead use a stub we'll create a stub object that has the same interface as Port, ensuring the methods on our object are spies so we can listen in on them in our test specs. Inside Ship.test.js - in the beforeEach - we want to change the following:
to:
Then we can remove our assertion that port.ships no longer contains our ship. We have to do so, as the reasoning for even having this test was that we knew if port.ships did contain the ship, that our setSail method was making the call to port.removeShip. Now we're isolating our test and stubbing Port, we can do this more efficiently with a spy.
Instead of asserting on port.ships, we'll assert that our Ship instance's setSail method calls the removeShip method on our Port-like stub. Because we've tested removeShip separately inside Port.test.js, we can have complete confidence that despite test isolation, our application will have full test coverage.
This can be demonstrated can set sail test. Change your test code from:
To:
gets added to port on instantiation
Our Ship constructor calls a port's addShip method in its constructor, so our Port-like stub's addShip method gets called in the beforeEach callback prior to each test running. Therefore, we just have to assert in this test that addShip was called.
Change:
to:
can dock at a different port
This one's on you! Continue with the calais stub of Port.