The other day I was navigating through the unit tests code written by one of my juniors. That part of the code was testing the Store Selectors. For beginners it is tempting to think that testing the Selectors also requires somehow mocking the Store since the Selectors read the state from the Store. That setup seems complex and entirely unnecessary since we are doing Unit Testing and therefore should be able to test the Selectors separately.
Curiously I went to see if NgRx has provided some capabilities to unit test the selectors separately without having to mock the Store. Luckily they have and its really a piece of cake. They have provided a magic function projector which is available with selectors where you can pass any states and the selector will produce the result. Enough talking, let see it in action.
Lets start by defining the state. We usually do it in the reducer file.
Pretty staright forward. Now let define some selectors.
In the snippet above we have two simple seletors getProductEntities and getSelectedProductId. We also have getProductsAsArray selector that uses the result from another selector getProductEntities. And finally we also have getSelectedProduct selector that uses two other selectors getProductEntities and getSelectedProductId.
[amazon_auto_links id=”529″]That is basically the setup. Now we are good to write the unit tests. For this we will only cover the last two selectors since everything will be covered with that.
As we have seen getProductsAsArray selector uses the result of one other selector as input.
does it mean to test that selector we need to test its input selector as well? No! we don’t need to. We can simply project what state this selector is expecting and wait for the result.
Simple right! Now let us look at getSelectedProduct Selector that uses inputs from two other selectors
and here is how we can write a unit test for this