-
Notifications
You must be signed in to change notification settings - Fork 92
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: new way to spy output without any
assertion
#462
Comments
Thanks for the input @lacolaco ! I agree that the current design works, but can be improved. test('output emits a value', async () => {
const submitFn = jest.fn();
const { outputs } = await render(SignalInputComponent, {
componentInputs: {
greeting: 'Hello',
name: 'world',
},
componentOutputs: {
submit: createOutputListener(submitFn)
}
});
await userEvent.click(screen.getByRole('button'));
expect(submitFn).toHaveBeenCalledWith('world');
}); That being said, I like your approach as well, and I think it will work better with Angular in the future (if something will be changed for Let's think on this for a while - I'll also send a tweet of other opinions (feel free to do this as well). |
@timdeschryver unfortunately the current approach of overriding the @Component({...})
class MyComponent {
@Output() readonly myEvent = fromEvent<MouseEvent>(inject(ElementRef).nativeElement, 'click')
} Overriding Although it was never intended like this, it always worked and eventually became official when angular introduced the imo the approach of simply overriding is questionable anyway as compared to Therefore an implementation like @lacolaco should be considered. or a type-safe approach could be preferred instead (and simply ignoring the output aliases): function subscribeToOutput<T>(
componentRef: ComponentRef<T>,
key: { [key in keyof T]: T[key] extends OutputRef<any> ? key : never }[keyof T],
spy: (value: any) => void,
) {
const unsubscribe = (componentRef.instance[key] as any).subscribe(spy)
componentRef.onDestroy(unsubscribe)
return unsubscribe
} ( |
@timdeschryver after digging into the code and thinking about it, I would propose an api like this: interface RenderComponentOptions<ComponentType> {
...
/**
* @description
* An object with key-value pairs to subscribe to EventEmitters of the component where `key` is the actual property name (no alias support) and value the callback function to subscribe with.
*
* @default
* {}
*
* @example
* const sendValue = (value) => { ... }
* await render(AppComponent, {
* subscribeToOutputs: {
* send: (_v:any) => void
* }
* })
*/
subscribeToOutputs?: {
[key in keyof ComponentType as ComponentType[key] extends OutputRef<any> ? key : never]?: ComponentType[key] extends OutputRef<infer U> ? (val: U) => void : never
};
...
} The What do you think? Would be happy to create a PR --> proposed implementation |
Thanks for the input and the effort @mumenthalers . My initial thought is to merge these changes in ATL. |
@timdeschryver Totally I like @mumenthalers 's |
@mumenthalers feel free to create a PR, we can further discuss it there (if needed) :) |
@all-contributors please add @lacolaco for ideas |
@lacolaco already contributed before to ideas |
Context
I think that there is some pains in spying on the output of a component, which is typified by the fact that you have to use type assertions by
any
. It is my opinion that the cost to pay for simply subscribing to events emitted by a component and inspecting their values can be lesser.https://github.com/testing-library/angular-testing-library/blob/main/apps/example-app/src/app/examples/22-signal-inputs.component.spec.ts#L51-L66
Goals
any
assertions in output testing scenarioIdea
This is a pseudo code and has not been strictly validated for feasibility.
outputs
to RenderResultoutputs.get(name)
can get a output ref by alias-aware nameoutputs.get(eventName)
The
eventName
should be same to its name in HTML template,<some-cmp (eventName)="..." />
.Angular's
ComponentMirror
hasoutputs
getter which returns a record ofpropName
andtempalteName
of outputs. So I think ALT can map theeventName
to corresponding property.https://github.com/angular/angular/blob/main/packages/core/src/render3/component.ts#L104-L139
The text was updated successfully, but these errors were encountered: