mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-05-13 16:13:03 +08:00
60 lines
2.8 KiB
Markdown
60 lines
2.8 KiB
Markdown
# Testing with Component Harnesses
|
|
|
|
Component harnesses are the standard, preferred way to interact with components in tests. They provide a robust, user-centric API that makes tests less brittle and easier to read by insulating them from changes to a component's internal DOM structure.
|
|
|
|
## Why Use Harnesses?
|
|
|
|
- **Robustness:** Tests don't break when you refactor a component's internal HTML or CSS classes.
|
|
- **Readability:** Tests describe interactions from a user's perspective (e.g., `button.click()`, `slider.getValue()`) instead of through DOM queries (`fixture.nativeElement.querySelector(...)`).
|
|
- **Reusability:** The same harness can be used in both unit tests and E2E tests.
|
|
|
|
Angular Material provides a test harness for every component in its library.
|
|
|
|
## Using a Harness in a Unit Test
|
|
|
|
The `TestbedHarnessEnvironment` is the entry point for using harnesses in unit tests.
|
|
|
|
### Example: Testing with a `MatButtonHarness`
|
|
|
|
```ts
|
|
import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed';
|
|
import {MatButtonHarness} from '@angular/material/button/testing';
|
|
import {MyButtonContainerComponent} from './my-button-container.component';
|
|
|
|
describe('MyButtonContainerComponent', () => {
|
|
let fixture: ComponentFixture<MyButtonContainerComponent>;
|
|
let loader: HarnessLoader;
|
|
|
|
beforeEach(async () => {
|
|
await TestBed.configureTestingModule({
|
|
imports: [MyButtonContainerComponent, MatButtonModule],
|
|
}).compileComponents();
|
|
|
|
fixture = TestBed.createComponent(MyButtonContainerComponent);
|
|
// Create a harness loader for the component's fixture
|
|
loader = TestbedHarnessEnvironment.loader(fixture);
|
|
});
|
|
|
|
it('should find a button with specific text', async () => {
|
|
// Load the harness for a MatButton with the text "Submit"
|
|
const submitButton = await loader.getHarness(MatButtonHarness.with({text: 'Submit'}));
|
|
|
|
// Use the harness API to interact with the component
|
|
expect(await submitButton.isDisabled()).toBe(false);
|
|
await submitButton.click();
|
|
|
|
// ... assertions
|
|
});
|
|
});
|
|
```
|
|
|
|
### Key Concepts
|
|
|
|
1. **`HarnessLoader`**: An object used to find and create harness instances. Get a loader for your component's fixture using `TestbedHarnessEnvironment.loader(fixture)`.
|
|
|
|
2. **`loader.getHarness(HarnessClass)`**: Asynchronously finds and returns a harness instance for the first matching component.
|
|
|
|
3. **`HarnessClass.with({ ... })`**: Many harnesses provide a static `with` method that returns a `HarnessPredicate`. This allows you to filter and find components based on their properties, like text, selector, or disabled state. Always use this to precisely target the component you want to test.
|
|
|
|
4. **Harness API:** Once you have a harness instance, use its methods (e.g., `.click()`, `.getText()`, `.getValue()`) to interact with the component. These methods automatically handle waiting for async operations and change detection.
|