Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/471.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/30.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用NGRX存储测试异步角度验证器_Javascript_Angular_Rxjs_Ngrx - Fatal编程技术网

Javascript 使用NGRX存储测试异步角度验证器

Javascript 使用NGRX存储测试异步角度验证器,javascript,angular,rxjs,ngrx,Javascript,Angular,Rxjs,Ngrx,我有一个用于被动表单的异步验证器,它在模糊时发送一个动作。这个动作会触发一个效果,它会对来自服务的一些数据进行处理 在验证器中,我使用选择器监听存储,并使用rxjs操作符以我需要的形式获取数据。这很有效。然而,我被困在这个函数的测试范围内。为什么我的测试没有涵盖整个操作 用户名验证程序 这是目前的报道: TLDR:为什么它缺少这个覆盖范围,这是模拟商店的正确方法吗?您返回的是一个在测试中从未订阅过的可观察对象。它是订阅返回的可观察对象的行为,在 .pipe( take(2),

我有一个用于被动表单的异步验证器,它在模糊时发送一个动作。这个动作会触发一个效果,它会对来自服务的一些数据进行处理

在验证器中,我使用选择器监听存储,并使用rxjs操作符以我需要的形式获取数据。这很有效。然而,我被困在这个函数的测试范围内。为什么我的测试没有涵盖整个操作

用户名验证程序

这是目前的报道:


TLDR:为什么它缺少这个覆盖范围,这是模拟商店的正确方法吗?

您返回的是一个在测试中从未订阅过的可观察对象。它是订阅返回的可观察对象的行为,在

.pipe(
    take(2),
    tap((val) => console.log(val)),
    filter(isUnique => isUnique !== undefined),
    map(isUnique => isUnique ? null : {usernameIsNotUnique: true}),
 )
您需要测试从返回的可观察对象发出的值

let validationResult;
const sub = UniqueUsernameValidator(storeMock)(control.value).subscribe(result => {
  validationResult = result;
});
sub.unsubscribe();
expect(validationResult.usernameIsNotUnique).toEqual(true);
看到您知道可观察对象是用of创建的,您可以这样展开它,但是如果可观察对象是异步的,则需要进行异步测试

我使用这个helper函数来异步测试可观察对象

import { Observable, Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';

export async function firstEmitted<T>(obs$: Observable<T>): Promise<T> {
    return new Promise<T>(resolve => {
        const finalise = new Subject<void>();
        obs$.pipe(takeUntil(finalise)).subscribe(value => {
            finalise.next();
            resolve(value);
        });
    });
}


让一些人困惑的是,第一个async是角度测试模块中的async函数,表示测试函数是anync函数,第二个将函数标记为async,因为我们在函数中使用了Wait运算符。

这是一个很好的答案,谢谢。在helper函数中,为什么要使用takeUntil操作符?这样你就能创造出一个有限的可观察的反应吗?此外,如果是这种情况,订阅中的finalize.next是否完成了可观察订阅,以便它可以返回值?takeUntil在被观察的可观察对象发出后完成可观察订阅。它是一种模式,用于拥有一个可以完成多个观察的观察对象,而不是跟踪一堆订阅。在我的助手的情况下,我真的不需要这种模式,只需要使用take1而不是takeuntil。我将实际更改我的代码以使用take1,现在您已经让我考虑过了,因为它更高效一点。
let validationResult;
const sub = UniqueUsernameValidator(storeMock)(control.value).subscribe(result => {
  validationResult = result;
});
sub.unsubscribe();
expect(validationResult.usernameIsNotUnique).toEqual(true);
import { Observable, Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';

export async function firstEmitted<T>(obs$: Observable<T>): Promise<T> {
    return new Promise<T>(resolve => {
        const finalise = new Subject<void>();
        obs$.pipe(takeUntil(finalise)).subscribe(value => {
            finalise.next();
            resolve(value);
        });
    });
}
it('should dispatch an action of CheckUsername', async(async () => {
  const validationResult = await firstEmitted(UniqueUsernameValidator(storeMock)(control.value));
  expect(validationResult.usernameIsNotUnique).toEqual(true);
}));
async(async () =>