0

这是一个带有加载器的 $resource 测试

describe('Service: MultiCalculationsLoader', function(){

  beforeEach(module('clientApp'));

  var MultiCalculationLoader,
    mockBackend,
    calculation;

  beforeEach(inject(function (_$httpBackend_, Calculation, _MultiCalculationLoader_) {
    MultiCalculationLoader = _MultiCalculationLoader_;
    mockBackend = _$httpBackend_;
    calculation = Calculation;
  }));

  it('should load a list of calculation from a user', function(){
    mockBackend.expectGET('/api/user/600/calculation').respond([{id:5}]);

     var calculations;
     var mockStateParams = {
       userId: 600
     };
    var promise = new MultiCalculationLoader(mockStateParams);

    promise.then(function(res){
      calculations = res
    });

    expect(calculations).toBeUndefined();

    mockBackend.flush();

    expect(calculations).toEqual([{id:5}]);
  });

});

当我运行测试时,我收到以下错误:

Expected [ { id : 5 } ] to equal [ { id : 5 } ].
Error: Expected [ { id : 5 } ] to equal [ { id : 5 } ].
    at null.<anonymous> 

我不明白。这两个数组对我来说是一样的。任何人的想法?

更新 这里的实现:

 .factory('Calculation', function ($resource) {
    return $resource('/api/user/:userId/calculation/:calcId', {'calcId': '@calcId'});
  })
  .factory('MultiCalculationLoader', function (Calculation, $q) {
    return function ($stateParams) {
      var delay = $q.defer();
      Calculation.query( {userId: $stateParams.userId},function (calcs) {
        delay.resolve(calcs);
      }, function () {
        delay.reject('Unable to fetch calculations');
      });
      return delay.promise;
    };
  })
4

3 回答 3

2

您期望的网址与实际网址不同。我想你需要这样的东西:

it('should load a list of calculation from a user', function(){
    //remove the 's' from 'calculations'
    mockBackend.expectGET('/api/user/600/calculation').respond([{id:5}]);

    var calculations;
    var promise = MultiCalculationLoader({userId:600}); //userId = 600
    promise.then(function(res){
      calculations = res
    });

    expect(calculations).toBeUndefined();

    mockBackend.flush();

    expect(calculations).toEqual([{id:5}]);
  });

还有一个问题是 Angular 会自动在响应中添加 2 个属性:

在此处输入图像描述

http://plnkr.co/edit/gIHolGd85SLswzv5VZ1E?p=preview

这有点像:AngularJS + Jasmine: Comparing objects

当角度将响应转换为资源对象时,这确实是角度 $resource 的问题。为了验证来自 $resource 的响应,您可以尝试angular.equals

expect(angular.equals(calculations,[{id:5},{id:6}])).toBe(true);

http://plnkr.co/edit/PrZhk2hkvER2XTBIW7yv?p=preview

您还可以编写自定义匹配器:

beforeEach(function() {
    jasmine.addMatchers({
      toEqualData: function() {
        return {
          compare: function(actual, expected) {
            return {
              pass: angular.equals(actual, expected)
            };
          }
        };
      }
    });
  });

并使用它:

expect(calculations).toEqualData([{id:5},{id:6}]);

http://plnkr.co/edit/vNfRmc6R1G69kg0DyjZf?p=preview

于 2014-08-24T13:30:25.957 回答
0

you can try change toEqual() with toEqualData()

expect(calculations).toEqualData([{id:5}]);
于 2014-07-14T16:28:27.433 回答
0

当您只想检查是否相等时,Jasmine 相等选择器有时可能过于具体。

在比较对象或数组时,我从未见过使用 toEqual() 方法,但使用 toBe() 方法定义。

尝试用 toMatch() 替换 toEqual()。

同样在单元测试中,我建议使用一个常量值,您可以在响应和 matchers/equal/toBe's 中传递该值。

describe('Service: MultiCalculationsLoader', function(){

  beforeEach(module('clientApp'));

  var MultiCalculationLoader,
    mockBackend,
    calculation,
    VALUE = [{id:5}];

  beforeEach(inject(function (_$httpBackend_, Calculation, _MultiCalculationLoader_) {
    MultiCalculationLoader = _MultiCalculationLoader_;
    mockBackend = _$httpBackend_;
    calculation = Calculation;
  }));

  it('should load a list of calculation from a user', function(){
    mockBackend.expectGET('/api/user/600/calculations').respond(VALUE);

    var calculations;
    var promise = MultiCalculationLoader();
    promise.then(function(res){
      calculations = res
    });

    expect(calculations).toBeUndefined();

    mockBackend.flush();

    expect(calculations).toEqual(VALUE);
  });

});

使用这种方法,我认为 .toEqual 实际上会起作用。

我们的方法:

块前:

httpBackend.when('JSONP', PATH.url + 'products?callback=JSON_CALLBACK&category=123').respond(CATEGORIES[0]);

测试:

describe('Category Method', function () {

        it('Should return the first category when the method category is called', function () {
            var result = '';

            service.category(123).then(function(response) {
                result = response;
            });

            httpBackend.flush();
            expect(result).toEqual(CATEGORIES[0]);

        });
    });
于 2014-05-08T19:39:31.217 回答