testing-library / angular-testing-library

🐙 Simple and complete Angular testing utilities that encourage good testing practices
https://testing-library.com/angular
MIT License
717 stars 90 forks source link

Support `on` with `render` that receive an template #470

Open timdeschryver opened 3 months ago

timdeschryver commented 3 months ago

Using on should also work with template renders.

https://github.com/testing-library/angular-testing-library/blob/ef521727d9a5a60a998e2ef5f5406400be2a9a0c/apps/example-app/src/app/examples/02-input-output.spec.ts#L35C1-L60C4

@mumenthalers do you have an idea how this can work?

edgargonzalez525 commented 2 months ago

this issue is also present when using inputs not only outputs @timdeschryver

mumenthalers commented 2 months ago

When providing a template rather than a component type, the WrapperComponent is used with it's template part overwritten.

@timdeschryver I don't think it would be useful to support on and inputs for templates. The main task for them is to subscribe to existing observables , and to provide values to existing inputs while providing supportive types.

I'd propose to only work with componentProperties when using a template as this already works perfectly for this case . Maybe the signature could be changed accordingly (to only support componentProperties when providing a template) afaik there is no other way to achieve this binding than to write component properties of the WrapperComponent.

--> imo the componentProperties should definitely not be deprecated

  it('template test', async () => {
    @Component({standalone: true, template:`<button (click)="event.emit()">{{value()}}</button>`, selector: 'app-test'})
    class AppTestComponent {
      readonly value = input.required<string>()
      readonly event = output<void>()
    }
    const value = 'foo bar'
    const fn = jest.fn()
    const result = await render(
      '<app-test [value]="value" (event)="fn($event)"/>',
      {
        imports: [AppTestComponent],
        componentProperties: { value, fn }
      }
    )
    const button = result.getByRole('button')
    expect(button).toHaveTextContent(value)
    button.click()
    expect(fn).toHaveBeenCalled()
  })
timdeschryver commented 2 months ago

@mumenthalers that's a valid point, and something I was also thinking. This is something we can do for the next major release. Thanks for your input, it's appreciated!