typescript 为Angular Jasmine组件服务调用实现抛出错误的最佳方法?

nafvub8i  于 2023-05-30  发布在  TypeScript
关注(0)|答案(1)|浏览(242)

我正在尝试用angular和typescript测试这个服务调用。我们使用的测试文件的典型设置是使用存根和这些列出的相关方法,但我想知道利用这种方法来模拟这些服务的HTTP调用的最佳方法是什么?
我特别努力地实现这个方法的catchError部分的测试,因为看起来throwError已经被弃用了,其他实现函数的尝试只会导致类型脚本错误,说Error不能被分配给validateSubscription服务调用的预期返回类型。

validateSubscription(SubscriptionID: string) {
    this.SubscriptionService
        .validateSubscription(SubscriptionID)
        .pipe(
            tap((result) => {
                if (result.item1 === true) {
                    this.commonService.showAlertHtml(
                        this.translate.instant('LABELS.VALIDATION_SUCCESS'),
                        this.translate.instant('LABELS.SUCCESS'),
                        false,
                        this.translate.instant('LABELS.OK'),
                        () => {
                            return null;
                        },
                        () => {
                            return null;
                        }
                    );
                } else if (result.item1 === false) {
                    this.commonService.showAlertHtml(
                        this.translate.instant(result.item2),
                        this.translate.instant('LABELS.ERROR'),
                        false,
                        this.translate.instant('LABELS.OK'),
                        () => {
                            return null;
                        },
                        () => {
                            return null;
                        }
                    );
                }
            }),
            catchError((error) => {
                this.commonService.showAlertHtml(
                    this.translate.instant('LABELS.VALIDATION_ERROR_'),
                    this.translate.instant('LABELS.ERROR'),
                    false,
                    this.translate.instant('LABELS.OK'),
                    () => {
                        return null;
                    },
                    () => {
                        return null;
                    }
                );
                throw error;
            })
        )
        .subscribe();
}

如果有人可以提供帮助,如何最好地修改我的代码,使功能测试,这将是理想的。我在下面附上了一个测试文件的尝试。

describe('NetworkSettingsComponent', () => {
    let component: SettingsComponent;
    let fixture: ComponentFixture<SettingsComponent>;

    const mockSubscriptions: Subscription[] = [
        {
            name: 'Sub 1',
            email: 'testuser@test.com',
        },
        {
            name: 'Sub 2',
            email: 'testuser2@test.com',
        }
    ];

    const translateServiceStub = { instant: (string) => string };
    const subscriptionServiceStub: Partial<SubscriptionService> = {
        validateSubscription: (): Observable<UpdateResponse> => of({ item1: true, item2: 'Success' })
    };
    const commonServiceStub: Partial<CommonService> = {
        showAlertHtml: () => ({ subscribe: () => ({}) })
    };
    const notifyServiceStub: Partial<NotifyService> = {
        show: () => ({ subscribe: () => ({}) })
    };

    beforeEach(waitForAsync(() => {
        TestBed.configureTestingModule({
            imports: [TranslateModule, ReactiveFormsModule, FormsModule],
            declarations: [NetworkSettingsComponent],
            providers: [
                FormBuilder,
                { provide: SubscriptionService, useValue: subscriptionServiceStub },
                { provide: CommonService, useValue: commonServiceStub }
            ]
        })
            .compileComponents()
            .then(() => {
                fixture = TestBed.createComponent(NetworkSettingsComponent);
                component = fixture.componentInstance;
            });
    }));

    it('should create the component', () => {
        expect(component).toBeTruthy();
    });

    it('should call validateSubscriptionand display an error alert', () => {
        const errorMessage = 'Error occurred';
        const subscriptionId = 'testSubscriptionId';
        const subscriptionServiceStub = TestBed.inject(SubscriptionService);
        spyOn(subscriptionServiceStub, 'validateSubscription').and.returnValue(
            throwError({ message: errorMessage })
        );

        const commonServiceStub = TestBed.inject(CommonService);
        spyOn(commonServiceStub, 'showAlertHtml');

        component.validateSubscription(subscriptionId);

        expect(subscriptionServiceStub.validateSubscription).toThrowError();
        expect(commonServiceStub.showAlertHtml).toHaveBeenCalled();
        expect(commonServiceStub.showAlertHtml).toHaveBeenCalledWith(
            'LABELS.VALIDATION_ERROR',
            'LABELS.ERROR',
            false,
            'LABELS.OK',
            jasmine.any(Function),
            jasmine.any(Function)
        );
    });

        
});
67up9zun

67up9zun1#

我会做以下修改,注意评论用!!:

it('should call validateSubscriptionand display an error alert', () => {
        const errorMessage = 'Error occurred';
        const subscriptionId = 'testSubscriptionId';
        const subscriptionServiceStub = TestBed.inject(SubscriptionService);
        spyOn(subscriptionServiceStub, 'validateSubscription').and.returnValue(
            // !! This way of using throwError is deprecated, have to pass a function now.
            // !! If it complains about the types, try adding the as any at the end
            throwError(() => ({ message: errorMessage })) as any
        );

        const commonServiceStub = TestBed.inject(CommonService);
        spyOn(commonServiceStub, 'showAlertHtml');

        component.validateSubscription(subscriptionId);
        
        // !! The line below might not pass since it is RxJS, not sure though.
        expect(subscriptionServiceStub.validateSubscription).toThrowError();
        expect(commonServiceStub.showAlertHtml).toHaveBeenCalled();
        expect(commonServiceStub.showAlertHtml).toHaveBeenCalledWith(
            'LABELS.VALIDATION_ERROR',
            'LABELS.ERROR',
            false,
            'LABELS.OK',
            jasmine.any(Function),
            jasmine.any(Function)
        );
    });

相关问题