Releases: getsaf/shallow-render
v8.0.3
v8.0.2
v8.0.1
Jest 🎉
Now with official support for Jest!
Thanks to @kreatemore for the PR and @kylecannon for the issue.
v8.0.0
Recursive Partial Mocks!!!
You can now provide partial mocks for component inputs and service mocks everywhere!
type Car = {
year: 2000;
vin: string;
engine: {
cylinders: number;
displacement: number;
}
}
Before v8.0 you could provide a partial for the top-level properties only. This means you'd have to specify a FULL engine property, even if your component only needs the cylinders
property, geez!):
shallow.render({bind: {car: {year: 2000, engine: {displacement: 5, cylinders: 6}}}});
Or even worse, you'd have to hard-cast stuff! 😧
shallow.render({bind: {car: {year: 2000, engine: <Car['engine']>{cylinders: 6, whoops: 'this slipped through!'}}}});
With v8.0, it's partials all-the-way-down!!
shallow.render({bind: {car: {year: 2000, engine: {cylinders: 6}}}});
This works with service mocks too:
shallow.mock(CarService, fetch: () => ({year: 2000, engine: {cylinders: 6}}));
Assert on outputs without referencing the instance
Shallow#render now returns an outputs object. The outputs object only allows referencing the EventEmitter properties of the test component that have been marked with @output.
it('emits "FOO" on button click', async () => {
const {find, instance} = await shallow.render();
find('button').triggerEventHandler('click', null);
expect(instance.mySelectOutput.emit) // <-- ☹️ Boooo accessing the instance!!
.toHaveBeenCalledWith('FOO');
});
We can avoid the use of the component instance like this:
it('emits "FOO" on button click', async () => {
const {find, outputs} = await shallow.render();
find('button').triggerEventHandler('click', null);
expect(outputs.mySelectOutput.emit) // 😎
.toHaveBeenCalledWith('FOO');
});
-- or, if you want to get weird with it --
it('emits "FOO" on button click', async (done) => {
const {find, outputs} = await shallow.render();
outputs.mySelectOutput.subscribe(value => { // 🤔
expect(value).toBe('FOO');
done();
})
find('button').triggerEventHandler('click', null);
});
v7.2.0
There was an issue found by @ike18t where components that were rendered with no template (eg: shallow.render({bind: {label: 'foo'}})
) would not accept changes when fixture.detectChanges()
was called.
It seems to be a limitation of TestBed and the solution is to always wrap components in a host component.
This release wraps all template-less renders in a host component which now means all renders have a host component.
Possible Breakage
If your tests use template-less renders and access the component directly via fixture.componentInstance
, this will break those tests.
If this affects you, change the test to grab the instance
property off of the shallow rendering instead of fixture.componentInstance
. This is the preferred method with shallow tests.
Example:
Bad fixture usage
it('uses fixture instead of instance', async () => {
const {fixture} = await shallow.render();
expect(fixture.componentInstance.foo).toBe('foo');
});
Corrected version
it('uses shallow instance correctly', async () => {
const {instance} = await shallow.render();
expect(instance.foo).toBe('foo');
});
v7.1.3
v7.1.2
v7.1.1
Fix for issues #81, #82, #78, #60
There's a feature that I have while mocking components that attempts to "correct" for components that do not have a selector defined (because the TestBed JIT Compiler bombs when it sees such a component).
Here's the function that applies the "correction".
It looks like the selector I used to correct with was a tag selector and apparently, that breaks the EmptyOutletComponent
mocking because I think it's trying to generate an open and close tag for the component dynamically. I switched the selector to a css-class selector (prefixing it with a .
) and it seems to have solved that template parse error!!! Wooo!!!! This has been bugging folks for a while! I've got a PR (#82) up with the fix.
Here's the line that fixes it!
I should note that just because this bypasses that explosion, it's still recommended that you use the RouterTestingModule
in your tests. This fix will just address the red-herring error message that is currently seen when mocking the RouterModule
directly.
v7.1.0
Ease up on module matching for replaceModule
.
Addresses some issues discussed in #60
Namely, this makes replaceModule(FooModule, FooTestingModule)
replace all ModuleWithProviders
that have FooModule
specified at their ngModule
property get the replacement.
TLDR:
You can now use shallow.replaceModule(RouterModule, RouterTestingModule.withRoutes(testRoutes);
. Before this change, it was much more complicated to use test modules.