【问题标题】:Angular2 Test HTTP Service Put - res.json() not a functionAngular2 测试 HTTP 服务放置 - res.json() 不是函数
【发布时间】:2016-06-28 14:33:33
【问题描述】:

我正在尝试使用 Karma + Jasmine 对我的一项服务的 PUT 功能进行单元测试。我的 GET 测试工作得很好,但是当我尝试为我的 PUT 函数运行测试时,我不断收到错误消息,说 res.json() 不是函数。我在这里想念什么?我按照此处所述的测试设置进行了操作:http://chariotsolutions.com/blog/post/testing-http-services-angular-2-jasmine/

服务sn-p:

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import {FormularyDrug} from '../models/formularydrug';
import { Http, Response, RequestOptions, Headers, Request, RequestMethod} from '@angular/http';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';

@Injectable()
export class FormularyDrugService {
    saveFormularyDrug(drug: FormularyDrug) : Observable<FormularyDrug>{
        let body = JSON.stringify({ drug });
        let headers = new Headers({ 'Content-Type': 'application/json' });
        let options = new RequestOptions({ url: this.formularyDrugURL + drug.DrugId, headers: headers });
        return this.http.put(this.formularyDrugURL + drug.DrugId, body, options)
            .map(this.extractData)
            .catch(this.handleError);
    }
    private extractData(res: Response) {
        let body = res.json();
        return body || [];
    }
    private handleError(error: any) {
        let errMsg = error.message || error.statusText || 'Server error';
        console.error(errMsg);
        return Observable.throw(errMsg);
    }
}

测试类:

import {describe, expect, it, xit, inject, injectAsync, beforeEachProviders} from '@angular/core/testing';
import {provide} from '@angular/core';
import {Headers, HTTP_PROVIDERS, BaseRequestOptions, XHRBackend, Response, ResponseOptions} from '@angular/http';
import {MockBackend, MockConnection} from '@angular/http/testing';

import {FormularyDrugService} from '../services/formularydrugs'
import {FormularyDrug} from '../models/formularydrug'

import 'rxjs/Rx'

describe('FormularyDrugService', () => {

  // All heed this block - it is required so that the test injector
  // is properly set up. Without doing this, you won't get the
  // fake backend injected into Http.

  // Also, you need to inject MockBackend as a provider before you wire
  // it to replace XHRBackend with the provide function!  So this is all
  // extremely important to set up right.
  beforeEachProviders(() => {
      return [
          HTTP_PROVIDERS,
          provide(XHRBackend, {useClass: MockBackend}),
          FormularyDrugService
      ];
  });

  // This test passes without issues
  it('should get list of formularyDrugs', inject([XHRBackend, FormularyDrugService], (mockBackend, drugService) => {
      mockBackend.connections.subscribe(
          (connection: MockConnection) => {
              connection.mockRespond(new Response(
                  new ResponseOptions({
                      body: [{ DrugId: 123 }]
                  }
                  )));
          });

      drugService.getFormularyDrugs().subscribe((drugs: FormularyDrug[]) => {
          expect(drugs.length).toBe(1);
          expect(drugs[0].DrugId).toBe(123);
      });
  }));

  // This returns error -- res.json() is not a function
  it('should save existing formularyDrug', injectAsync([XHRBackend, FormularyDrugService], (mockBackend, drugService) => {
      return new Promise((resolve, reject) => {
          let data: FormularyDrug = new FormularyDrug("BrandName", "GenericName", "TAB", "2mg", "(2mL)", 1);

          mockBackend.connections.subscribe(connection => {
              connection.mockRespond(new ResponseOptions({ body: [{ DrugId: 1 }] }));
          });

          drugService.saveFormularyDrug(data).subscribe((drug: FormularyDrug) => {
              expect(drug).toBeDefined();
              expect(drug.DrugId).toBe(1);
              resolve();
          });
      });
  }), 300);

});

错误信息:

ERROR: 'res.json is not a function'
Chrome 51.0.2704 (Windows 10 0.0.0): Executed 1 of 2 SUCCESS (0 secs / 0.024 secs)
Chrome 51.0.2704 (Windows 10 0.0.0) FormularyDrugService should save existing formularyDrug FAILED
        Failed: Uncaught (in promise): res.json is not a function
            at ZoneDelegate.invoke (c:/Users/bharris/Source/Repos/Project/UI/node_modules/zone.js/dist/zone.js:323:29)

【问题讨论】:

    标签: angular unit-testing karma-jasmine


    【解决方案1】:

    在对该服务进行其他单元测试后,我注意到我在模拟响应中发回的对象是一个数组而不是单个对象。这并没有完全解决我的问题,但是当我从 injectAsync 切换到 injection 时,我能够让测试成功执行。

    这是我更新的测试:

    it('should save existing formularyDrug', inject([XHRBackend, FormularyDrugService], (mockBackend, drugService) => {
      mockBackend.connections.subscribe(
          (connection: MockConnection) => {
              connection.mockRespond(new Response(
                  new ResponseOptions({
                      body: { DrugId: 123 }
                  }
                  )));
          });
    
      let data: FormularyDrug = new FormularyDrug("BrandName", "GenericName", "TAB", "2mg", "(2mL)", 1);
    
      drugService.saveFormularyDrug(data).subscribe((drug: FormularyDrug) => {
          expect(drug).toBeDefined();
          expect(drug.DrugId).toBe(123);
      });
    }));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-01-10
      • 1970-01-01
      • 1970-01-01
      • 2018-11-10
      • 1970-01-01
      • 2017-10-07
      • 2018-03-19
      相关资源
      最近更新 更多