getsaf / shallow-render

Angular testing made easy with shallow rendering and easy mocking. https://getsaf.github.io/shallow-render
MIT License
273 stars 25 forks source link

Usage with AsyncPipe? #161

Closed hmil closed 4 years ago

hmil commented 4 years ago

Hi,

What is the recommended way to work with async pipes and shallow-render?

What I have is a component which passes a value to a child component using an async pipe.

@Component({
template: `
<div>
<my-child-component value="someObservable | async">
</div>
`
})
class MyComponent {
    readonly someObservable = this.someService.observeStuff$;
}

In my test, I would like to simulate events from someService and then check that MyComponent is forwarding the value to MyChildComponent like this:

const rendering = new Shallow(MyComponent, MyModule).render();
const fakeEvent = { hello: 'world' };

/* Some black magic to emit a value from someService.observeStuff$. I already have this stuff working. */

// This does not work. `value` is always null despite many attempts to use fakeAsync, detectChanges, flush and so on.
expect(rendering.findComponent(MyChildComponent).value).toBe({ hello: 'world'});

However, I think that shallow-render is somehow mocking AsyncPipe and this prevents the mocked ChildComponent from receiving the value.

What would be the proper way to make this work?

getsaf commented 4 years ago

My best guess is that shallow-render is waiting for the first render to be stable before resolving the promise. You can turn this off with an option on the render itself:

shallow.render({whenStable: false});
// or
shallow.render('<foo></foo>', {whenStable: false});

Here's a StackBlitz example of a test that uses fakeAsync and whenStable. I'm not sure if I am reproducing your scenario properly here but this is where I thought to look first based on your description. If this doesn't solve it for you, can you make some alterations to that StackBlitz to more accurately describe your issue? I'm sure we can figure it out quickly.

https://stackblitz.com/edit/github-au24hp?file=examples/simple-component.spec.ts

hmil commented 4 years ago

Oh jeez in fact it works even without whenStable.

My component was doing some rxjs pipework before passing the result to the AsyncPipe and this had a bug.

So sorry for being such a noob. May this issue help future troubled souls coming across it.

Async pipes work as you'd expect in shallow-render. If you don't see the value being updated in your test, then it's most likely a bug in your own code.

Thank you for the quick turnaround and the example which convinced me to look at my code once more.

getsaf commented 4 years ago

Glad it worked out! At least it's a good example of how testing can produce higher quality code!