跳至主要内容

API

Angular Testing Library 重新导出 DOM Testing Library 中的所有内容,以及 render 方法。

以下重新导出已修补以使其更易于与 Angular 一起使用

  • fireEvent 上的事件在事件触发后会自动调用更改检测周期
  • findBy 查询会在调用查询函数之前自动调用更改检测周期
  • waitFor 函数会在调用回调函数之前自动调用更改检测周期

render

使用 Angular Testing Library,可以通过组件类型或模板两种方式渲染组件。

默认情况下,render 还会导入 NoopAnimationsModule

Type

要渲染组件,需要将组件类型传递给 render 方法。对于不使用应用程序其他部分的组件(例如设计模块或服务),渲染组件就像以下示例一样简单。

await render(AppComponent)

template

除了将组件类型作为第一个参数传递,还可以提供模板。这种做法是渲染指令所必需的,但也可以应用于组件,甚至可能更有用。然后必须将指令(或组件)类型添加到 declarations 中。

使用指令的示例:

await render('<div appSpoiler></div>', {
declarations: [SpoilerDirective],
})

使用组件的示例:

await render(
'<app-component [value]="47" [otherValue]="anotherValue" (sendValue)="sendValue($event)"></app-component>',
{
declarations: [AppComponent],
componentProperties: {
anotherValue: 'valueOfAnotherProperty',
sendValue: jest.fn(),
},
},
)
export async function render<ComponentType>(
component: Type<ComponentType>,
renderOptions?: RenderComponentOptions<ComponentType>,
): Promise<RenderResult<ComponentType, ComponentType>>
export async function render<WrapperType = WrapperComponent>(
template: string,
renderOptions?: RenderTemplateOptions<WrapperType>,
): Promise<RenderResult<WrapperType>>

Component RenderOptions

inputs

一个用于设置组件的 @Inputinput() 属性的对象。

默认 : {}

await render(AppComponent, {
inputs: {
counterValue: 10,
// explicitly define aliases using `aliasedInput`
...aliasedInput('someAlias', 'someValue'),
},
})

on

一个包含回调的对象,用于订阅组件的 EventEmittersObservables

默认 : {}

// using a manual callback
const sendValue = (value) => { ... }
// using a (jest) spy
const sendValueSpy = jest.fn()

await render(AppComponent, {
on: {
send: (value) => sendValue(value),
send: sendValueSpy
}
})

declarations

渲染组件所需的组件、指令和管道的集合。例如,组件的嵌套组件。

有关更多信息,请参阅 Angular 文档

默认 : []

示例:

await render(AppComponent, {
declarations: [CustomerDetailComponent, ButtonComponent],
})

deferBlockBehavior

设置延迟块的行为。

有关更多信息,请参阅 Angular 文档

默认 : undefined(使用 DeferBlockBehavior.Manual,这与 Angular 的默认值 DeferBlockBehavior.Playthrough 不同)

示例:

await render(AppComponent, {
deferBlockBehavior: DeferBlockBehavior.Playthrough,
})

deferBlockStates

设置组件中延迟块的初始状态。

有关更多信息,请参阅 Angular 文档

默认 : undefined(使用 Angular 的默认值,即 DeferBlockState.Placeholder

示例:

await render(FixtureComponent, {
deferBlockStates: DeferBlockState.Loading,
})

componentProviders

渲染组件所需的通过依赖项注入提供的提供程序集合。

这些将在组件级别提供。要以模块级别注入依赖项,请使用 providers

有关更多信息,请参阅 Angular 文档

默认 : []

示例:

await render(AppComponent, {
componentProviders: [AppComponentService],
})

componentImports

一个导入集合,用于覆盖独立组件的导入。

默认 : undefined

示例:

await render(AppComponent, {
componentImports: [MockChildComponent],
})

childComponentOverrides

指定要覆盖的子组件的提供程序集合。

默认 : undefined

示例:

await render(AppComponent, {
childComponentOverrides: [
{
component: ChildOfAppComponent,
providers: [{provide: ChildService, useValue: {hello: 'world'}}],
},
],
})

detectChangesOnRender

在渲染组件后调用 detectChanges

默认 : true

示例:

await render(AppComponent, {detectChangesOnRender: false})

autoDetectChanges

像“真实”运行的组件一样自动检测更改。例如,在事件发生时运行更改检测周期。

默认 : true

示例:

await render(AppComponent, {
autoDetectChanges: false,
})

excludeComponentDeclaration

排除自动添加为声明的组件。当组件在导入的模块中声明时需要这样做,例如使用 SCAM。

默认 : false

示例:

await render(AppComponent, {
imports: [AppModule], // a module that includes AppComponent
excludeComponentDeclaration: true,
})

imports

渲染组件所需的导入集合,例如共享模块。如果 BrowserAnimationsModule 未添加到集合中,则默认情况下会添加 NoopAnimationsModule

有关更多信息,请参阅 Angular 文档

默认 : [NoopAnimationsModule]

示例:

await render(AppComponent, {
imports: [AppSharedModule, MaterialModule],
})

providers

渲染组件所需的通过依赖项注入提供的提供程序集合。

这些将在模块级别提供。要以组件级别注入依赖项,请使用 componentProviders

有关更多信息,请参阅 Angular 文档

默认 : []

示例:

await render(AppComponent, {
providers: [
CustomersService,
{
provide: MAX_CUSTOMERS_TOKEN,
useValue: 10,
},
],
})

queries

要绑定的查询。覆盖 DOM Testing Library 中的默认设置,除非合并。

默认 : undefined

示例:

await render(AppComponent, {
queries: {...queries, ...customQueries},
})

routes

要通过 RouterTestingModule.withRoutes 设置路由服务的路由配置。有关更多信息,请参阅 Angular 路由文档

默认 : []

示例:

await render(AppComponent, {
declarations: [ChildComponent],
routes: [
{
path: '',
children: [
{
path: 'child/:id',
component: ChildComponent,
},
],
},
],
})

schemas

渲染组件所需的架构集合。允许的值是 NO_ERRORS_SCHEMACUSTOM_ELEMENTS_SCHEMA

有关更多信息,请参阅 Angular 文档

默认 : []

示例:

await render(AppComponent, {
schemas: [NO_ERRORS_SCHEMA],
})

removeAngularAttributes

从夹具中删除 Angular 属性(ng-version 和 root-id)。

默认 : false

示例:

await render(AppComponent, {
removeAngularAttributes: true,
})

componentInputs(已弃用)

一个用于设置组件 @Input 属性的对象。使用 setInput 来设置输入属性。如果组件属性没有用 @Input 属性进行注释,则会抛出错误。

默认 : {}

示例:

await render(AppComponent, {
componentInputs: {
counterValue: 10,
},
})

componentOutputs(已弃用)

一个用于设置组件 @Output 属性的对象。

默认 : {}

示例:

await render(AppComponent, {
componentOutputs: {
clicked: (value) => { ... }
}
})

componentProperties(已弃用)

一个用于设置组件 @Input@Output 属性的对象。没有像 inputson 那样细粒度的控制。

默认 : {}

示例:

await render(AppComponent, {
componentProperties: {
// an input
counterValue: 10,
// an output
send: (value) => { ... }
// a public property
name: 'Tim'
}
})

RenderResult

container

已渲染的 Angular 组件的包含 DOM 节点。这是一个常规 DOM 节点,因此可以调用 container.querySelector 等来检查子节点。

debug

以语法高亮的方式打印出组件的 DOM。接受一个可选参数,用于打印出特定的 DOM 节点。

const {debug} = await render(AppComponent)

debug()

rerender

通过遵循 Angular 组件生命周期事件来更改现有组件实例的输入属性(即 ngOnChanges 被调用)。未定义的输入属性将被清除。

const {rerender} = await render(Counter, {
inputs: {count: 4, name: 'Sarah'},
})

expect(screen.getByTestId('count-value').textContent).toBe('4')
expect(screen.getByTestId('name-value').textContent).toBe('Sarah')

await rerender({
inputs: {count: 7},
})

// count is updated to 7
expect(screen.getByTestId('count-value').textContent).toBe('7')
// name is undefined because it's not provided in rerender
expect(screen.getByTestId('name-value').textContent).toBeUndefined()

使用 partialUpdate,只有新提供的属性才会被更新。未提供的其他输入属性不会被清除。

const {rerender} = await render(Counter, {
inputs: {count: 4, name: 'Sarah'},
})

expect(screen.getByTestId('count-value').textContent).toBe('4')
expect(screen.getByTestId('name-value').textContent).toBe('Sarah')

await rerender({inputs: {count: 7}, partialUpdate: true})

// count is updated to 7
expect(screen.getByTestId('count-value').textContent).toBe('7')
// name is still rendered as "Sarah" because of the partial update
expect(screen.getByTestId('name-value').textContent).toBe('Sarah')

detectChanges

触发组件的更改检测周期。

有关更多信息,请参阅 Angular 文档

debugElement

组件的 Angular DebugElement

有关更多信息,请参阅 Angular 文档

fixture

组件的 Angular ComponentFixture

有关更多信息,请参阅 Angular 文档

const {fixture} = await render(AppComponent)

// componentInstance is typed as AppComponent
const componentInstance = fixture.componentInstance

🚨 如果发现自己使用 fixture 访问组件的内部值,则应该重新考虑!这可能意味着,你正在测试实现细节。

接受 DOM 元素或路径作为参数。如果传递的是元素,navigate 将导航到元素的 href 值。如果传递的是路径,navigate 将导航到该路径。

const { navigate } = await render(AppComponent, {
routes: [...]
})

await navigate(component.getByLabelText('To details'))
await navigate('details/3')

...queries

render 的最重要的功能是,来自 DOM Testing Library 的查询会自动返回,它们第一个参数绑定到正在测试的组件。

有关完整列表,请参阅 查询

示例:

const {getByText, queryByLabelText} = await render(AppComponent)

screen.getByRole('heading', {
name: /api/i,
})
queryByLabelText(/First name/i')

renderDeferBlock

要测试 延迟视图,可以使用 renderDeferBlockrenderDeferBlock 将为特定的延迟块设置所需的延迟状态。延迟视图的默认值为 Placeholder,但也可以在渲染组件时设置初始状态。

const {renderDeferBlock} = await render(FixtureComponent, {
deferBlockStates: DeferBlockState.Loading,
})

expect(screen.getByText(/loading/i)).toBeInTheDocument()

await renderDeferBlock(DeferBlockState.Complete)
expect(screen.getByText(/completed/i)).toBeInTheDocument()