gpt4 book ai didi

angular - 使用 RxJS Marbles 测试 Angular 响应式表单

转载 作者:行者123 更新时间:2023-12-03 09:27:32 24 4
gpt4 key购买 nike

Angular 组件

public setupObservables() {
this.formFieldChanged$ = this.formField
.valueChanges
.pipe(
debounceTime(100),
distinctUntilChanged((a, b) => a === b),
)
}

Jasmine 测试

import { of } from 'rxjs';
import { marbles } from 'rxjs-marbles/jasmine';
...

it('should update value on debounced formField change', marbles(m => {
const values = { a: "1", b: "2", c: "3" };

const fakeInputs = m.cold('a 200ms b 50ms c', values);
const expected = m.cold('100ms a 250ms c', values);

// works on stackblitz but otherwise gives TS2540 compiler error
// cannot assign to a read-only property
component.formField.valueChanges = fakeInputs;
component.setupObservables();

m.expect(component.formFieldChanged$).toBeObservable(expected);
}));

stackblitz.com example

目的是使用大理石测试来测试 Observable使用 Angular react 形式的上下文中的代码。
  • 这种方法有意义吗?
  • 如何最好地模拟 valueChangesFormField目的?
  • 有没有更好的方法来构建这类测试?
  • 最佳答案

    问题是 - 你想测试什么。它是单元测试还是 e2e 测试?
    如果它是一个单元测试 - 模拟 react 形式,只涵盖你的逻辑,那么你对 valueChanges 没有问题,因为它被 mock 并且你控制它。

    如果它是一个 e2e 测试 - 你不应该重新分配 valueChanges .什么都不应该被 mock /替换,因为它是一个 e2e 测试。

    不过,如果您想更改 valueChanges - 使用 https://github.com/krzkaczor/ts-essentials#writable

    (Writable<typeof component.formField>component.formField).valueChanges = fakeInputs; 

    它将使属性类型可写。

    如果它是一个单元测试,我个人会投票模拟 react 形式,因为在单元测试中我们只需要测试我们的单元,它的依赖关系应该被模拟/ stub 。

    注入(inject)我们要模拟的零件

    作为一个选项,您可以将表单作为组件的依赖项移动到组件声明中的提供程序。

    @Component({
    selector: 'app-component',
    templateUrl: './app-component.html',
    styleUrls: ['./app-component.scss'],
    providers: [
    {
    provide: 'form',
    useFactory: () => new FormControl(),
    },
    ],
    })
    export class AppComponent {
    public formFieldChanged$: Observable<unknown>;

    constructor(@Inject('form') public readonly formField: FormControl) {
    }

    public setupObservables(): void {
    this.formFieldChanged$ = this.formField
    .valueChanges
    .pipe(
    debounceTime(100),
    distinctUntilChanged((a, b) => a === b),
    );
    }
    }

    然后你可以简单地在测试中注入(inject)一个模拟而不是它。

    it('should update value on debounced formField change', marbles(m => {
    const values = { a: "1", b: "2", c: "3" };

    const fakeInputs = m.cold('a 200ms b 50ms c', values);
    const expected = m.cold('100ms a 250ms c', values);

    const formInput = {
    valueChanges: fakeInputs,
    };

    const component = new AppComponent(formInput as any as FormControl);

    component.setupObservables();
    m.expect(component.formFieldChanged$).toBeObservable(expected);
    }));

    关于angular - 使用 RxJS Marbles 测试 Angular 响应式表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61274166/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com