Angular $ httpBackend whenPUT()的行为与whenGET()的行为不同吗?

时间:2016-06-30 13:01:34

标签: angularjs jasmine ecmascript-6 angular-mock

我正在编写一个将使用API​​的Angular服务的开头,我开始剔除所有请求操作。这项服务实际上没有发生任何事情;它基本上是$http的包装器。我遇到了一个有趣的测试问题:我已经嘲笑了PUT请求似乎没有按照我的预期工作,我想知道我的理解失败了。< / p>

基本上,当我检查observation.get(1)时,请求被正确模拟并且测试通过。但如果我observation.update({'some_key': 'some_value'}),我会收到此错误:

Chrome 51.0.2704 (Mac OS X 10.11.5) Observation responds to #save FAILED
    Error: No response defined !

我想我已经在beforeEach()函数体中定义了一个响应,但规范仍然失败。看起来很奇怪,其他所有测试都使用完全相同的语法。我做错了什么?

等级(适用于ES6)

class Observation {
  constructor($http, AppSettings) {
    'ngInject';
    Object.assign(this, {$http, AppSettings});
    this.headers = {
      'Authorization': 'Token token=myfancytoken'
    };
    this.endpoint = `${this.AppSettings.API_URL}/api/${this.AppSettings.API_VERSION}/observations`;
  }

  get(id) {
    this.id = id;
    let params = {
      url: `${this.endpoint}/${this.id}.json`,
      method: 'GET'
    };
    return this.request(params);
  }

  save(data) {
    if (typeof this.id === 'undefined') {
      throw {message: 'Cannot save object without an id'};
    }
    let params = {
      url: `${this.endpoint}/${this.id}.json`,
      method: 'PUT',
      data: data
    };
    return this.request(params);
  }

  request(params) {
    Object.assign(params, {headers: this.headers});
    return this.$http(params)
      .then((response) => { return response.data; })
      .catch((response) => { return response.status; });
  }

  /*
  * Other actions omitted for brevity
  */
}

export default Observation;

规格

import Observation from './observation';

describe('Observation', () => {
  let $httpBackend, AppSettings, observation, $http, obj, successResponse;

  beforeEach(() => {
    AppSettings = {
      "API_URL": 'http://localhost:3000',
      'API_VERSION': 'v1'
    };

    inject(($injector) => {
      $httpBackend = $injector.get('$httpBackend');
      $http = $injector.get('$http');
    });

    observation = new Observation($http, AppSettings);

    successResponse = (response) => {
      obj = response.data;
    };

    /* Mock the backend */

    // GET #show
    $httpBackend
      .when('GET', `${observation.endpoint}/1.json`)
      .respond(200, {data: {}});

    // PUT #save
    // FIXME: Not working for some reason and needs to be defined in the test itself?
    $httpBackend
      .when('PUT', `${observation.endpoint}/${observation.id}.json`)
      .respond(200, {data: {'id': 1}});
  });

  afterEach(function() {
    $httpBackend.verifyNoOutstandingExpectation();
    $httpBackend.verifyNoOutstandingRequest();
  });


  it('responds to #get', () => {
    observation
      .get(1)
      .then(successResponse);

    $httpBackend.expect('GET', `${observation.endpoint}/1.json`)
    $httpBackend.flush();

    expect(obj).toEqual({});
  });

  /* Other test cases omitted for brevity */

  it('responds to #save', () => {
    observation.id = 1;
    observation
      .save({'first_name': 'Lisa'})
      .then(successResponse);

    // FIXME: Why doesn't this work?
    $httpBackend
      .expect('PUT', `${observation.endpoint}/${observation.id}.json`);
      // .respond(200, {data: {'id': 1}});
    $httpBackend.flush();

    expect(obj.id).toBe(1);
  });

  it('throws an error if #save is called without an id on the object', () => {
    expect(() => {observation.save()}).toThrowError(Error, 'Cannot save object without an id');
  });

});

1 个答案:

答案 0 :(得分:2)

$httpBackend
  .when('PUT', `${observation.endpoint}/${observation.id}.json`)

此时observation没有ID。