【问题标题】:Does Angular $httpBackend whenPUT() behave differently than whenGET()?Angular $httpBackend whenPUT() 的行为是否与 whenGET() 不同?
【发布时间】:2016-06-30 21:39:13
【问题描述】:

我正在编写一个将使用 API 的 Angular 服务的开头,并且我从删除所有请求操作开始。这项服务实际上还没有发生任何事情;它基本上是$http 的包装器。我在测试中遇到了一个有趣的问题:我已经模拟了一个 PUT 请求,该请求似乎没有像我预期的那样工作,我想知道我的理解失败的地方。

基本上,当我检查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');
  });

});

【问题讨论】:

    标签: angularjs jasmine ecmascript-6 angular-mock


    【解决方案1】:
    $httpBackend
      .when('PUT', `${observation.endpoint}/${observation.id}.json`)
    

    此时observation 没有id。

    【讨论】:

    • 天哪。我好蠢。谢谢!
    猜你喜欢
    • 2016-01-01
    • 2015-05-16
    • 2021-12-03
    • 1970-01-01
    • 2016-03-09
    • 1970-01-01
    • 2012-06-05
    • 2016-04-19
    • 1970-01-01
    相关资源
    最近更新 更多