Javascript 在AngularJS中测试加载程序

Javascript 在AngularJS中测试加载程序,javascript,angularjs,karma-jasmine,Javascript,Angularjs,Karma Jasmine,这是一个带有加载程序的$resource测试 describe('Service: MultiCalculationsLoader', function(){ beforeEach(module('clientApp')); var MultiCalculationLoader, mockBackend, calculation; beforeEach(inject(function (_$httpBackend_, Calculation, _MultiCal

这是一个带有加载程序的$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> 

Jasmine等式选择器有时太特殊了,当你只是想检查等式时

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

尝试用toMatch()替换toEqual()

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

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]);

        });
    });
您可以尝试使用toEqualData()更改toEqual()


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

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会自动向响应添加两个属性:

这与以下问题是一样的:

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

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

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

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

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

无法使用常量值。但它确实对toMatch()有效。谢谢!嗯,奇怪-这正是我们在单元测试中采用的方法。。。尝试返回值[0]并测试该值是否相等。可能与expectGET vs when方法以及它们返回数据的方式有关……“toMatch”似乎接受任何内容。所以它没有起作用。回到原点。还有其他想法吗?你有3个选择-toMatch、toBe、ToeQual找不到“toEqualData”函数?它似乎有效:@KhanhTO Yeha,但它在我的开发环境中不起作用。你能展示一下你的
多计算加载程序
是如何实现的吗?实现工作正常。只是我的测试不起作用。我只是怀疑你的
MultiCalculationLoader
中有一个问题导致测试失败,是不是有点混乱?也许我已经完全离开这里了,但是使用angular.toJson怎么样?我认为这会从数组中删除“垃圾”?@user1572526:我发现我们可以使用
angular.equals
来实现这一点<代码>angular.equals将在testing@user1572526:您还可以编写自定义匹配器。请参阅更新的答案
beforeEach(function() {
    jasmine.addMatchers({
      toEqualData: function() {
        return {
          compare: function(actual, expected) {
            return {
              pass: angular.equals(actual, expected)
            };
          }
        };
      }
    });
  });
expect(calculations).toEqualData([{id:5},{id:6}]);