Thanks to visit codestin.com
Credit goes to github.com

Skip to content

feat(core): support bindings in TestBed #62040

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

Closed
wants to merge 1 commit into from

Conversation

crisbeto
Copy link
Member

@crisbeto crisbeto commented Jun 13, 2025

Adds support for passing in Binding objects into TestBed.createComponent. This makes it easier to test components by avoiding the need to create a wrapper component. Furthermore, it keeps the behavior consistent between tests and the actual app. For example, given a custom checkbox that looks like this:

@Component({
  selector: 'my-checkbox',
  template: '...',
  host: {'[class.checked]': 'isChecked()'}
})
export class MyCheckbox {
  isChecked = input(false);
}

A test for the isChecked input would look something like this:

it('should toggle the checked class', () => {
  @Component({
    imports: [MyCheckbox],
    template: '<my-checkbox [isChecked]="isChecked"/>',
  })
  class Wrapper {
    isChecked = false;
  }

  const fixture = TestBed.createComponent(Wrapper);
  const checkbox = fixture.nativeElement.querySelector('my-checkbox');
  fixture.detectChanges();
  expect(checkbox.classList).not.toContain('checked');

  fixture.componentInstance.isChecked = true;
  fixture.detectChanges();
  expect(checkbox.classList).toContain('checked');
});

Whereas with the new API, the test would look like this:

it('should toggle the checked class', () => {
  const isChecked = signal(false);
  const fixture = TestBed.createComponent(MyCheckbox, {
    bindings: [inputBinding('isChecked', isChecked)]
  });
  const checkbox = fixture.nativeElement.querySelector('my-checkbox');
  fixture.detectChanges();
  expect(checkbox.classList).not.toContain('checked');

  isChecked.set(true);
  fixture.detectChanges();
  expect(checkbox.classList).toContain('checked');
});

@crisbeto crisbeto added action: review The PR is still awaiting reviews from at least one requested reviewer target: minor This PR is targeted for the next minor release labels Jun 13, 2025
@angular-robot angular-robot bot added detected: feature PR contains a feature commit area: core Issues related to the framework runtime labels Jun 13, 2025
@ngbot ngbot bot added this to the Backlog milestone Jun 13, 2025
@crisbeto crisbeto force-pushed the test-component-bindings branch from 274b4a4 to 9611870 Compare June 13, 2025 07:12
@crisbeto crisbeto marked this pull request as ready for review June 13, 2025 07:22
@pullapprove pullapprove bot requested review from atscott and thePunderWoman June 13, 2025 07:22
@crisbeto crisbeto changed the title feat(core): support bindings TestBed feat(core): support bindings in TestBed Jun 14, 2025
Adds support for passing in `Binding` objects into `TestBed.createComponent`. This makes it easier to test components by avoiding the need to create a wrapper component. Furthermore, it keeps the behavior consistent between tests and the actual app. For example, given a custom checkbox that looks like this:

```typescript
@component({
  selector: 'my-checkbox',
  template: '...',
  host: {'[class.checked]': 'isChecked()'}
})
export class MyCheckbox {
  isChecked = input(false);
}
```

A test for the `isChecked` input would look something like this:

```typescript
it('should toggle the checked class', () => {
  @component({
    imports: [MyCheckbox],
    template: '<my-checkbox [isChecked]="isChecked"/>',
  })
  class Wrapper {
    isChecked = false;
  }

  const fixture = TestBed.createComponent(Wrapper);
  const checkbox = fixture.nativeElement.querySelector('my-checkbox');
  fixture.detectChanges();
  expect(checkbox.classList).not.toContain('checked');

  fixture.componentInstance.isChecked = true;
  fixture.detectChanges();
  expect(checkbox.classList).toContain('checked');
});
```

Whereas with the new API, the test would look like this:

```typescript
it('should toggle the checked class', () => {
  const isChecked = signal(false);
  const fixture = TestBed.createComponent(MyCheckbox, {
    bindings: [inputBinding('isChecked', isChecked)]
  });
  const checkbox = fixture.nativeElement.querySelector('my-checkbox');
  fixture.detectChanges();
  expect(checkbox.classList).not.toContain('checked');

  isChecked.set(true);
  fixture.detectChanges();
  expect(checkbox.classList).toContain('checked');
});
```
@crisbeto crisbeto force-pushed the test-component-bindings branch from 9611870 to 49a1f83 Compare June 14, 2025 05:00
Copy link
Contributor

@thePunderWoman thePunderWoman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

reviewed-for: fw-general, public-api

@pullapprove pullapprove bot requested a review from mmalerba June 16, 2025 08:44
Copy link
Contributor

@atscott atscott left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reviewed-for: public-api

@crisbeto crisbeto added action: merge The PR is ready for merge by the caretaker and removed action: review The PR is still awaiting reviews from at least one requested reviewer labels Jun 16, 2025
@pkozlowski-opensource
Copy link
Member

This PR was merged into the repository by commit 2e0c98b.

The changes were merged into the following branches: main

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
action: merge The PR is ready for merge by the caretaker area: core Issues related to the framework runtime detected: feature PR contains a feature commit target: minor This PR is targeted for the next minor release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants