首页 > 解决方案 > Angular 6 中的服务测试 - mockBackend

问题描述

我正在尝试在我的服务中测试一个返回 observable (BehaviorSubject) 的函数。

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class TopicsService {
  private topics = [];
  private obs = new BehaviorSubject<any>(this.topics);

  constructor(private http: HttpClient) {}

  getTopics(): BehaviorSubject<any> {
    if (!this.topics.length) {
      this.http.get('http://localhost:8089/topics')
        .subscribe(
          (topicsData: any) => {
            this.topics = topicsData;
            this.obs.next(this.topics);
          }
        );
    }

    return this.obs;
  }

然后我创建了一个我希望在 Http 假调用中接收到的 mockResponse 对象。然后我调用 getTopics() 函数并订阅 Observable,我希望得到的实际上是响应的主体:

import { TestBed, inject } from '@angular/core/testing';
import { HttpClient, HttpHandler } from '@angular/common/http';
import { ConnectionBackend, ResponseOptions } from '@angular/http';
import { MockBackend } from '@angular/http/testing';

import { TopicsService } from './topics.service';

describe('TopicsService', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [
        TopicsService, HttpClient, HttpHandler,
        { provide: ConnectionBackend, useClass: MockBackend }
       ]
    });
  });

  describe('#getTopics()', () => {
    it('should be created', inject([TopicsService], (service: TopicsService) => {
      expect(service).toBeTruthy();
    }));

    it('should return a BehaviourSubject<any<Topic>>',
      inject([TopicsService, ConnectionBackend], (service: TopicsService, mockBackend) => {

      const mockResponse = {
          name: 'Chess',
          decription: 'Best chess courses'
      };

      mockBackend.connections.subscribe((connection) => {
        connection.mockRespond(new Response(new ResponseOptions({
          body: JSON.stringify(mockResponse)
        })));
      });

      service.getTopics().subscribe((topicData) => {
        expect(topicData.length).toBe(1);
        expect(topicData.name).toEqual('Chess');
        expect(topicData.description).toEqual('Best chess courses');
      });
    }));
  });
});

我显然做错了什么,但我似乎无法理解。提前非常感谢!

编辑:对不起,我忘了添加测试输出,我的错:

TopicsService #getTopics() should return a BehaviourSubject<any<Topic>> FAILED
        Expected 0 to be 1.
            at SafeSubscriber._next src/services/topics.service.spec.ts:38:34)
            at SafeSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.__tryOrUnsub node_modules/rxjs/_esm5/internal/Subscriber.js:195:1)
            at SafeSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.next node_modules/rxjs/_esm5/internal/Subscriber.js:133:1)
            at Subscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber._next node_modules/rxjs/_esm5/internal/Subscriber.js:77:1)
        Expected undefined to equal 'Chess'.
            at SafeSubscriber._next src/services/topics.service.spec.ts:39:32)
            at SafeSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.__tryOrUnsub node_modules/rxjs/_esm5/internal/Subscriber.js:195:1)
            at SafeSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.next node_modules/rxjs/_esm5/internal/Subscriber.js:133:1)
            at Subscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber._next node_modules/rxjs/_esm5/internal/Subscriber.js:77:1)
        Expected undefined to equal 'Best chess courses'.
            at SafeSubscriber._next src/services/topics.service.spec.ts:40:39)
            at SafeSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.__tryOrUnsub node_modules/rxjs/_esm5/internal/Subscriber.js:195:1)
            at SafeSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.next node_modules/rxjs/_esm5/internal/Subscriber.js:133:1)

标签: angulartestingangular-services

解决方案


推荐阅读