dojo dragon main logo

断言模板

断言模板(assertion template)提供一个可复用的基本模板来断言部件的整个输出内容,但在执行每个测试前可按需修改部分内容。这意味着在多次测试中都不会改变的公共元素可被抽象并定义一次,然后多处使用。

要使用断言模板,首先导入模块:

import assertionTemplate from '@dojo/framework/testing/assertionTemplate';

可创建一个基本断言,它定义了部件的默认渲染状态。假定有以下部件:

src/widgets/Profile.tsx

import { create, tsx } from '@dojo/framework/core/vdom';

import * as css from './styles/Profile.m.css';

export interface ProfileProperties {
    username?: string;
}

const factory = create().properties<ProfileProperties>();

const Profile = factory(function Profile({ properties }) {
    const { username } = properties();
    return <h1 classes={[css.root]}>{`Welcome ${username || 'Stranger'}!`}</h1>;
});

export default Profile;

基本断言如下所示:

tests/unit/widgets/Profile.tsx

const { describe, it } = intern.getInterface('bdd');
import harness from '@dojo/framework/testing/harness';
import assertionTemplate from '@dojo/framework/testing/assertionTemplate';
import { tsx } from '@dojo/framework/core/vdom';

import Profile from '../../../src/widgets/Profile';
import * as css from '../../../src/widgets/Profile.m.css';

const profileAssertion = assertionTemplate(() => (
    <h1 classes={[css.root]} assertion-key="welcome">
        Welcome Stranger!
    </h1>
));

在测试中这样写:

tests/unit/widgets/Profile.tsx

const profileAssertion = assertionTemplate(() => (
    <h1 classes={[css.root]} assertion-key="welcome">
        Welcome Stranger!
    </h1>
));

describe('Profile', () => {
    it('default renders correctly', () => {
        const h = harness(() => <Profile />);
        h.expect(profileAssertion);
    });
});

要测试为 Profile 传入 username 属性的场景,可以按如下方式为断言模板调参:

tests/unit/widgets/Profile.tsx

describe('Profile', () => {
    ...

    it('renders given username correctly', () => {
        // 使用给定的用户名更新期望的结果
        const namedAssertion = profileAssertion.setChildren('~welcome', () => [
            'Welcome Kel Varnsen!'
        ]);
        const h = harness(() => <Profile username="Kel Varnsen" />);
        h.expect(namedAssertion);
    });
});

这里使用 baseAssertion 的 setChildren() api,然后使用特定的 ~ 选择器来定位 key 值为 ~welcome 的节点。assertion-key 属性(当使用 w()v() 函数时为 ~key)是断言模板的一个特殊属性,在断言时会被删除,因此在匹配渲染结构时不会显示出来。此功能能让断言模板简单的选择节点,而不需要扩展实际的部件渲染函数。一旦找到 welcome 节点,它的子节点将被设置为新值 ['Welcome Kel Varnsen!'],然后在 h.expect 中使用生成的模板。需要注意的是,断言模板在设置值时总是返回一个新的断言模板,这可以确保现有模板不会被意外地修改,若被修改可能导致其他测试失败,并允许基于新模板,增量逐层构建出新的模板。

断言模板具有以下 API:

insertBefore(selector: string, children: () => DNode[]): AssertionTemplateResult;
insertAfter(selector: string, children: () => DNode[]): AssertionTemplateResult;
insertSiblings(selector: string, children: () => DNode[], type?: 'before' | 'after'): AssertionTemplateResult;
append(selector: string, children: () => DNode[]): AssertionTemplateResult;
prepend(selector: string, children: () => DNode[]): AssertionTemplateResult;
replaceChildren(selector: string, children: () => DNode[]): AssertionTemplateResult;
setChildren(selector: string, children: () => DNode[], type?: 'prepend' | 'replace' | 'append'): AssertionTemplateResult;
setProperty(selector: string, property: string, value: any): AssertionTemplateResult;
setProperties(selector: string, value: any | PropertiesComparatorFunction): AssertionTemplateResult;
getChildren(selector: string): DNode[];
getProperty(selector: string, property: string): any;
getProperties(selector: string): any;
replace(selector: string, node: DNode): AssertionTemplateResult;
remove(selector: string): AssertionTemplateResult;