feat(signals): signals testing package with provideMockSignalStore #4252
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
There is no auto-mock functionality for easily mock NgRx's
SignalStore
s andComponentStore
s. This PR contains theprovideMockSignalStore
function that provides a mock version of aSignalStore
:Signal
s are replaced byWritableSignal
sRxMethod
s are replaced byFakeRxMethod
sFunction
s are replaced by Sinon fakesWe can use the mocked
SignalStore
s in unit tests, Storybook stories and Storybook Play tests.FakeRxMethod
s are generated by thenewMockRxMethod()
function. AFakeRxMethod
is a function, that accepts a static value, signal, or an observable as an input argument. It has aFAKE_RX_METHOD
property, contains a Sinon fake. This Sinon fake stores the call information, when:FakeRxMethod
was called with a static valueFakeRxMethod
was called with a signal argument, and the signal's value changesFakeRxMethod
was called with an observable argument, and the observable emitsThe only limitation of
provideMockSignalStore
is that it can't alter theOnInit
andOnDestroy
hooks. To work around this limitation, I think it's a good practice to do the init/destroy tasks and connect the stores (if there are app / feature / component level stores) from the smart component that consumes the store. Alternatively, I can modify thesignal-store.ts
to support the mocking of theOnInit
andOnDestroy
hooks.I covered the feature with unit tests, and here are some additional examples where I use
provideMockSignalStore
on real components:I'll soon publish an article that explains how these examples work.
I'll create a separate PR for the
provideMockComponentStore
function, its source is available here, it works but needs some polishing. It uses the sameFakeRxMethod
as this PR for replacing theupdate
s andeffect
s of theComponentStore
.Related issue: #2767
I reused some parts (mostly types) of this PR: #3646 "feat(component-store): add a testing library", and I also read the feedback there, for example I use Sinon as @LayZeeDK suggested.
What is the current behavior?
What is the new behavior?
Does this PR introduce a breaking change?
Other information