【问题标题】:Angular Unittest jest throwError -> error gets not detectedAngular Unit Test jest throw Error -> 未检测到错误
【发布时间】:2021-08-04 14:15:57
【问题描述】:

假设我得到了一个使用以下方法的组件:

someMethod() {
  this.someService
    .doServicesMethod(this.id)
    .pipe(
      finalize(() => (this.loading = false)),
      catchError((e) => {
        this.showErrorMessage = true;
        return throwError(e);
      }),
    )
    .subscribe({
      next: (result) => {/* handle result*/},
    });
}

现在我想用 jest 写一个单元测试,所以我喜欢:

it(
  'should test someMethod',
  waitForAsync(() => {
    spyOn(someService, 'doServicesMethod').and.returnValue(throwError('someError'));

    expect(component.showErrorMessage).toBeFalsy();
    expect(component.loading).toBeTruthy();

    try {
      component.someMethod();
    } catch (error) {
      expect(component.loading).toBeFalsy();
      expect(component.showErrorMessage).toBeTruthy();
    }
  }),
);

但是单元测试不起作用。起初我尝试不使用waitForAsync,在这种情况下,在此测试中未检测到错误,但在测试后以某种方式浮动并在下一次测试中被检测到,然后以someError 失败。

使用 waitForAsync 会检测到错误,但不会在 try-catch-block 中检测到错误,在这种情况下测试本身会失败。

component.someMethod(); 检测到错误后调用tick();,因此测试跳转到catch 块,但错误实际上并没有被捕获 -> 无论如何测试都失败了someError

我有点想不通,所以有人知道我是如何让这个测试工作的吗?

【问题讨论】:

    标签: angular typescript unit-testing rxjs jestjs


    【解决方案1】:

    我一直使用expect().toThrow()或者expect().toThrowError()

    it('should test someMethod', async () => {
        expect( () => {
            await component.someMethod()
        }).toThrow();
    });
    

    您还可以使用toThrowError(<Replace with Error>) 捕获特定错误

    如果不使用承诺,我已经做到了:

    it('should test someMethod', () => {
        expect( () => {
            component.someMethod()
        }).toThrow( ... );
    });
    

    如果您的 try/catch 不起作用,并且此语法不起作用,您确定 someMethod 实际上是在抛出吗?

    我拥有的示例函数:

    export function ExpandTextStringToArray(
        DataField: string,
        Separator: string = ',',
        TrimText: boolean = false
    ): string[] {
        if (DataField === undefined || DataField === null) {
            throw new Error(APPLICATION_EXCEPTIONS.VALUE_MUST_BE_STRING);
        }
        const ExpandedString: string[] = DataField.split(Separator);
        if (TrimText) {
            ExpandedString.forEach((Text, Index, Data) => {
                Data[Index] = Text.trim();
            });
        }
        return ExpandedString;
    }
    

    我的测试,它有效并接住了投掷:

    it('should throw an exception when passing null for the DataField', () => {
        expect(() => {
            ExpandTextStringToArray(null);
        }).toThrowError(APPLICATION_EXCEPTIONS.VALUE_MUST_BE_STRING);
    });
    

    【讨论】:

    • 感谢您的回复,但该方法无效。 someMethod 不返回承诺,因此 await 没有任何内容,并且函数本身不会抛出(接收到的函数没有抛出)。
    • 现在更新了 Promise 响应的答案。我已经在我的库中操作数据的函数上做到了这一点。
    猜你喜欢
    • 1970-01-01
    • 2017-03-06
    • 1970-01-01
    • 2021-03-18
    • 1970-01-01
    • 2016-02-12
    • 1970-01-01
    • 2020-08-07
    • 2022-12-02
    相关资源
    最近更新 更多