繁体   English   中英

具有可观察对象和承诺的方法的单元测试

[英]Unit test for method with observables and promise

我有这种方法,我正在尝试为其编写单元测试。 当前的测试只是要以正确的顺序调用 spyOn 方法。

      handleSave() {
        this.saving = true;
        this.presenters.presentLoader({
          message: "Uploading..."
        });
        this.loginService.loginToFirebase().subscribe(() => {
          Promise.all(
            this.credential.inputs.map((input) => this.putStorageItem(input))
          )
          .then((url) => {
            this.presenters.dismissLoader();
            this.presenters.presentAlert({
              message: 'Successfully Uploaded Identification.',
              buttons: ['Ok']
            });
            this.presenters.dismissModal(true);
            this.saving = false
          })
          .catch((error) => {
            this.presenters.dismissLoader();
            this.presenters.presentAlert({
              message: 'Something went wrong.'
            });
            this.saving = false
          });
        })
      }

到目前为止,单元测试适用于 presentLoader 的初始调用,但随后的 dismissLoader(位于 loginToFirebase 可观察对象内,并且 Promise.all 没有被调用(至少在可观察对象和承诺解决之前)

在我之前,我模拟 putStorageItem component.putStorageItem = (item) => Promise.resolve(true); 在里面,我用这个来模拟 loginService。

    {
      provide: LoginService,
      useValue: {
        loginToFirebase: () => of(true)
      }
    },

我目前的测试

    it("call handle save should do stuff", () => {
        let presenters = TestBed.inject(PresentersService);
    
        spyOn(presenters, 'presentLoader');
        spyOn(presenters, 'dismissLoader');
        spyOn(presenters, 'presentAlert');
        spyOn(presenters, 'dismissModal');
    
        component.handleSave();
    
        expect(presenters.presentLoader).toHaveBeenCalled();
        expect(presenters.dismissLoader).toHaveBeenCalled();
        expect(presenters.presentAlert).toHaveBeenCalled();
        expect(presenters.dismissModal).toHaveBeenCalled();
    
      });

putStorageItem

      putStorageItem(input) {
        const fileExt = input.file.metadata.name.split('.').slice(-1);
        const filepath = ${input.label}.${fileExt}`;
        let task;
        if(input.file.metadata.isBase64) {
          task = this.fireStorage.ref(filepath).put(this.util.b64toBlob(input.file.img), {contentType:input.file.metadata.type, customMetadata:{originalName:input.file.metadata.name}});
        } else {
          task = this.fireStorage.ref(filepath).put(input.file.img, {contentType:input.file.metadata.type, customMetadata:{originalName:input.file.metadata.name}});
        }
        input.fileProgress = task.percentageChanges();
        return task.then((snapshot) => {
          console.log('One success:', input.file)
        }).catch((error) => {
          console.log('One failed:', input.file, error.message)
        });
      }

由于您使用的是Observables和/或promises ,因此您需要使用不同的技术进行测试。 这些技术是:

  • Jasmine 的done回调
  • Angular 的async/awaitfixture.whenStable()
  • Angular的waitForAsyncfixture.whenStable()
  • fakeAsync和 Angular 的tick

您还可以阅读更多关于 Angular 中的异步测试的信息。

我最喜欢的是fakeAsynctick ,我认为它可以在这种情况下帮助你。

// !! wrap the test in a `fakeAsync` so you have better control of promises
it("call handle save should do stuff", fakeAsync(() => {
        let presenters = TestBed.inject(PresentersService);
    
        spyOn(presenters, 'presentLoader');
        spyOn(presenters, 'dismissLoader');
        spyOn(presenters, 'presentAlert');
        spyOn(presenters, 'dismissModal');
    
        component.handleSave();
        // !! Call tick() to tell the test that before running the
        // statements below the tick, 
        // ensure the promises in the component code have resolved
        // since the expect statements rely on them.
        tick();
    
        expect(presenters.presentLoader).toHaveBeenCalled();
        expect(presenters.dismissLoader).toHaveBeenCalled();
        expect(presenters.presentAlert).toHaveBeenCalled();
        expect(presenters.dismissModal).toHaveBeenCalled();
    
      }));

tick也可用于确保可观察流的subscribe在继续之前已完成,但我主要将其用于承诺。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM