-
Notifications
You must be signed in to change notification settings - Fork 1
5. Testing
If you took a look at the commits, you may have noticed that the commit for the equip-item command contained a .spec file. This is a unit test for our handler. Let's dive a bit into that.
- Arrange, Act and Assert
Usually, each unit test follow the AAA pattern (Arrange, Act, Assert).
- During the Arrange phase, we setup all that we need for our test: mock adapters and entities.
- During the Act phase, we call our handler execute method with the right payload.
- During the Assert phase, we check that the result is what we expected: a
neverthrowmonad that should either beok(...)orerr(...)and that our entities have correctly changed.
- Dependency injection
NestJS makes a heavy use of the dependency injection design pattern. At runtime, our EquipItemCommandHandler will receive the correct adapters for its ports thanks to the provider mapping declared in HeroInfrastructure. But during a test, we can use the dependency injection to provide mock adapters for those ports.
If we check the handler constructor, we can see that we need to provide two adapters: one for heroPorts: UpdatePort<Hero> & GetByIdPort<Hero> and one for itemPresenter: Pick<ItemPresenter, 'getHeroInventory'>.
- Because heroPorts only use the basic CRUD ports, we can use the existing
HeroMockAdapter. This mock adapter already has all the CRUD operations (create, getAll, getById, update, and delete) for theHeroentity.
const heroMockAdapter = new HeroMockAdapter();- For the second port, because we used the
Pick<...>generic, we only need to mock thegetHeroInventorymethod.
const itemMockPresenter = {
getHeroInventory: jest.fn(),
}Now that we have all our mock adapters, we can instantiate our command handler.
const equipItemCommandHandler = new EquipItemCommandHandler(
heroMockAdapter,
itemMockPresenter,
);We are almost ready for the Act phase !
- Create test data
- Use the heroMockAdapter to create a test hero.
- Create a test item, you can either use an
itemMockAdapteror theitemEntityFactory. - Call
itemMockPresenter.getHeroInventory.mockResolvedValueOnceto set what should be returned by our mock method. depending on our test scenario, it could return an empty inventory or an array containing our test item. Don't forget to wrap it in aneverthrow Result.
- Execute
Now we can do the Act part of our test ! Create a EquipItemCommand with the test data as payload, and call the execute method of our equipItemCommandHandler.
- Assert
- Check the result of the command, you can use the
neverthrowmethodsisOk()orisErr(). - Check that the entities have been correctly modified.
Your unit test is done ! You should be able to test all the possible output of the handler. Don't forget to reset your mock adapters between each tests. Take a look at this file if you need help.