单元测试Angular服务

时间:2018-12-05 08:25:37

标签: javascript angular unit-testing jasmine observable

我正努力在Angular项目中测试服务。 该服务很小,但是我不知道如何在类中测试观察者。

我正在尝试测试此类的方法。公共方法必须按照其承诺做。当我调用“ pop”方法时,测试失败。 由于pop方法是公共方法,并且具有Message作为返回值,因此该方法在调用消息后应返回一条消息。在测试的情况下,基础代码不太重要。

测试失败的原因是因为那时观察者仍然不确定。我建议原因是因为在测试中调用pop方法时未执行回调方法,因此addMessage观察器尚未初始化。

由于我刚开始这个项目,所以我对有关代码的假设持谨慎态度。 有人对我如何测试此代码有建议吗?

pop方法是公共的还是应该是私有的?

编辑: pop方法由其他一些类使用,不能私有。 我的问题确实是:此服务的这种实现对吗?



    import { Injectable } from '@angular/core';
    import { Observable } from 'rxjs';
    import { share} from 'rxjs/operators';
    import { Observer } from 'rxjs';
    import { Message } from 'primeng/components/common/api';


    @Injectable()
    export class FeedBackService {
      obsAddMessage: Observable;
      obsClearMessages: Observable;
      /** @internal */
      private clearMessages: Observer;
      private addMessage: Observer;

      /**
       * Creates an instance of FeedBackService.
       */
      constructor() {
        this.obsAddMessage = new Observable(observer => this.addMessage = observer).pipe(share());
        this.obsClearMessages = new Observable(observer => this.clearMessages = observer).pipe(share());
      }


      /**
       * Synchronously create and show a new message instance.
       *
       * @param {(string | Message)} type The type of the message, or a Message object.
       * @param {string=} title The message title.
       * @param {string=} body The message body.
       * @returns {Message}
       *          The newly created Message instance.
       */
      pop( type: string | Message, title?: string, body?: string ): Message {
        const message: any = typeof type === 'string' ? {severity: type, summary: title, detail: body} : type;

        if (!this.addMessage) {
          throw new Error('No Containers have been initialized to receive messages.');
        } else {
          this.addMessage.next(message);
        }
        return message;
      }
    }

测试:


    import {Message} from 'primeng/components/common/api';
    import {FeedBackService} from './feedback.service';


    fdescribe('Service: Feedback', () => {

      let feedbackService: FeedBackService;
      const MESSAGE: Message = {severity: 'This is a message', summary: 'Title', detail: 'Body'};
      const SEVERITY = 'severity';
      const SUMMARY = 'summary';
      const DETAIL = 'detail';

      beforeEach(() => {
        feedbackService = new FeedBackService();
      });



      it('#pop should return the message when passing in a message', () => {
        let returnMessage = feedbackService.pop(MESSAGE);
        expect(returnMessage).toEqual(MESSAGE);
      });
    });

错误:

enter image description here

1 个答案:

答案 0 :(得分:1)

就像任何可观察的对象一样,obsAddMessage直到订阅后才会执行,因此,如您所展示的,如果您尝试在订阅前尝试输入新值,则观察者仍未定义。解决方案就是在调用feedbackService.pop()之前先建立一个订阅。

我设置了一个简单的Stackblitz来说明我的意思。该Stackblitz的规格为:

it('#pop should return the message when passing in a message', () => {
  feedbackService.obsAddMessage.subscribe(message => console.log(message));
  let returnMessage = feedbackService.pop(MESSAGE);
  expect(returnMessage).toEqual(MESSAGE);
});

我希望这会有所帮助。

相关问题