【问题标题】:Jasmine: toEqual() matcher does not work for array of objects?Jasmine:toEqual() 匹配器不适用于对象数组?
【发布时间】:2026-02-01 21:45:02
【问题描述】:

我正在尝试为我的一个范围变量编写规范,但即使它们匹配,它也失败了。

控制台:

  Expected [ { id: 1, name: 'Browns', created_at: '2014-08-06T21:38:41.000Z', updated_at: '2014-08-06T21:38:41.000Z' }, { id: 2, name: 'Blues', created_at: '2014-08-06T21:38:53.000Z', updated_at: '2014-08-06T21:38:53.000Z' }, { id: 3, name: 'Greens', created_at: '2014-08-06T21:39:03.000Z', updated_at: '2014-08-06T21:39:03.000Z' } ] to equal [ { id: 1, name: 'Browns', created_at: '2014-08-06T21:38:41.000Z', updated_at: '2014-08-06T21:38:41.000Z' }, { id: 2, name: 'Blues', created_at: '2014-08-06T21:38:53.000Z', updated_at: '2014-08-06T21:38:53.000Z' }, { id: 3, name: 'Greens', created_at: '2014-08-06T21:39:03.000Z', updated_at: '2014-08-06T21:39:03.000Z' } ].
    Error: Expected [ { id: 1, name: 'Browns', created_at: '2014-08-06T21:38:41.000Z', updated_at: '2014-08-06T21:38:41.000Z' }, { id: 2, name: 'Blues', created_at: '2014-08-06T21:38:53.000Z', updated_at: '2014-08-06T21:38:53.000Z' }, { id: 3, name: 'Greens', created_at: '2014-08-06T21:39:03.000Z', updated_at: '2014-08-06T21:39:03.000Z' } ] to equal [ { id: 1, name: 'Browns', created_at: '2014-08-06T21:38:41.000Z', updated_at: '2014-08-06T21:38:41.000Z' }, { id: 2, name: 'Blues', created_at: '2014-08-06T21:38:53.000Z', updated_at: '2014-08-06T21:38:53.000Z' }, { id: 3, name: 'Greens', created_at: '2014-08-06T21:39:03.000Z', updated_at: '2014-08-06T21:39:03.000Z' } ].

规格:

describe('ProductsIndexCtrl', function() {
  beforeEach(inject(function($controller, $rootScope, $injector) {
    scope = $rootScope.$new();

    $httpBackend = $injector.get('$httpBackend');
    $httpBackend.when('/api/color_groups').respond([{"id":1,"name":"Browns","created_at":"2014-08-06T21:38:41.000Z","updated_at":"2014-08-06T21:38:41.000Z"},{"id":2,"name":"Blues","created_at":"2014-08-06T21:38:53.000Z","updated_at":"2014-08-06T21:38:53.000Z"},{"id":3,"name":"Greens","created_at":"2014-08-06T21:39:03.000Z","updated_at":"2014-08-06T21:39:03.000Z"}]);
    $httpBackend.when('/api/shapes').respond([{"id":1,"name":"Round","created_at":"2014-05-23T17:10:32.000Z","updated_at":"2014-05-23T17:10:32.000Z"},{"id":2,"name":"Cat Eye","created_at":"2014-05-27T18:53:36.000Z","updated_at":"2014-05-27T18:53:36.000Z"},{"id":3,"name":"sharps","created_at":"2014-05-28T21:41:44.000Z","updated_at":"2014-07-02T14:13:59.000Z"},{"id":4,"name":"square","created_at":"2014-06-02T15:29:58.000Z","updated_at":"2014-06-02T15:29:58.000Z"},{"id":5,"name":"Round","created_at":"2014-06-02T15:35:06.000Z","updated_at":"2014-06-02T15:35:06.000Z"},{"id":6,"name":"fffff","created_at":"2014-07-02T14:14:23.000Z","updated_at":"2014-07-02T14:14:23.000Z"},{"id":7,"name":"Rectangular","created_at":"2014-07-29T15:17:01.000Z","updated_at":"2014-07-29T15:17:01.000Z"},{"id":8,"name":"Diamond","created_at":"2014-07-29T15:17:08.000Z","updated_at":"2014-07-29T15:17:08.000Z"}]);
    $httpBackend.when('/api/materials').respond([{"id":1,"name":"Steel","created_at":"2014-05-23T17:04:42.000Z","updated_at":"2014-05-23T17:04:42.000Z"},{"id":2,"name":"Cotton","created_at":"2014-05-23T17:04:47.000Z","updated_at":"2014-05-23T17:04:47.000Z"},{"id":3,"name":"woods","created_at":"2014-05-28T20:26:16.000Z","updated_at":"2014-07-02T14:35:09.000Z"},{"id":4,"name":"plastic","created_at":"2014-06-02T15:30:05.000Z","updated_at":"2014-06-02T15:30:05.000Z"},{"id":5,"name":"glass","created_at":"2014-06-02T15:34:58.000Z","updated_at":"2014-06-02T15:34:58.000Z"},{"id":7,"name":"wood","created_at":"2014-06-02T16:51:47.000Z","updated_at":"2014-06-02T16:51:47.000Z"},{"id":8,"name":"rubber","created_at":"2014-07-02T14:35:51.000Z","updated_at":"2014-07-02T14:35:51.000Z"},{"id":9,"name":"carbon","created_at":"2014-07-29T14:52:44.000Z","updated_at":"2014-07-29T14:52:44.000Z"},{"id":10,"name":"paper","created_at":"2014-07-29T14:53:31.000Z","updated_at":"2014-07-29T14:53:31.000Z"},{"id":11,"name":"sandpaper","created_at":"2014-07-29T14:56:39.000Z","updated_at":"2014-07-29T14:56:39.000Z"},{"id":12,"name":"xfsdfsf","created_at":"2014-07-29T14:56:44.000Z","updated_at":"2014-07-29T14:56:44.000Z"}]);

    ProductsIndexCtrl = $controller('ProductsIndexCtrl', {
      '$scope': scope
    });

    $httpBackend.expectGET('/api/color_groups').respond([{"id":1,"name":"Browns","created_at":"2014-08-06T21:38:41.000Z","updated_at":"2014-08-06T21:38:41.000Z"},{"id":2,"name":"Blues","created_at":"2014-08-06T21:38:53.000Z","updated_at":"2014-08-06T21:38:53.000Z"},{"id":3,"name":"Greens","created_at":"2014-08-06T21:39:03.000Z","updated_at":"2014-08-06T21:39:03.000Z"}]);
    $httpBackend.expectGET('/api/shapes').respond([{"id":1,"name":"Round","created_at":"2014-05-23T17:10:32.000Z","updated_at":"2014-05-23T17:10:32.000Z"},{"id":2,"name":"Cat Eye","created_at":"2014-05-27T18:53:36.000Z","updated_at":"2014-05-27T18:53:36.000Z"},{"id":3,"name":"sharps","created_at":"2014-05-28T21:41:44.000Z","updated_at":"2014-07-02T14:13:59.000Z"},{"id":4,"name":"square","created_at":"2014-06-02T15:29:58.000Z","updated_at":"2014-06-02T15:29:58.000Z"},{"id":5,"name":"Round","created_at":"2014-06-02T15:35:06.000Z","updated_at":"2014-06-02T15:35:06.000Z"},{"id":6,"name":"fffff","created_at":"2014-07-02T14:14:23.000Z","updated_at":"2014-07-02T14:14:23.000Z"},{"id":7,"name":"Rectangular","created_at":"2014-07-29T15:17:01.000Z","updated_at":"2014-07-29T15:17:01.000Z"},{"id":8,"name":"Diamond","created_at":"2014-07-29T15:17:08.000Z","updated_at":"2014-07-29T15:17:08.000Z"}]);
    $httpBackend.expectGET('/api/materials').respond([{"id":1,"name":"Steel","created_at":"2014-05-23T17:04:42.000Z","updated_at":"2014-05-23T17:04:42.000Z"},{"id":2,"name":"Cotton","created_at":"2014-05-23T17:04:47.000Z","updated_at":"2014-05-23T17:04:47.000Z"},{"id":3,"name":"woods","created_at":"2014-05-28T20:26:16.000Z","updated_at":"2014-07-02T14:35:09.000Z"},{"id":4,"name":"plastic","created_at":"2014-06-02T15:30:05.000Z","updated_at":"2014-06-02T15:30:05.000Z"},{"id":5,"name":"glass","created_at":"2014-06-02T15:34:58.000Z","updated_at":"2014-06-02T15:34:58.000Z"},{"id":7,"name":"wood","created_at":"2014-06-02T16:51:47.000Z","updated_at":"2014-06-02T16:51:47.000Z"},{"id":8,"name":"rubber","created_at":"2014-07-02T14:35:51.000Z","updated_at":"2014-07-02T14:35:51.000Z"},{"id":9,"name":"carbon","created_at":"2014-07-29T14:52:44.000Z","updated_at":"2014-07-29T14:52:44.000Z"},{"id":10,"name":"paper","created_at":"2014-07-29T14:53:31.000Z","updated_at":"2014-07-29T14:53:31.000Z"},{"id":11,"name":"sandpaper","created_at":"2014-07-29T14:56:39.000Z","updated_at":"2014-07-29T14:56:39.000Z"},{"id":12,"name":"xfsdfsf","created_at":"2014-07-29T14:56:44.000Z","updated_at":"2014-07-29T14:56:44.000Z"}]);

  }));

  it('sets color_groups', function() {
    $httpBackend.flush();
    console.log(JSON.stringify(scope.color_groups)); // prints the same object!!!
    expect(scope.color_groups).toEqual([{"id":1,"name":"Browns","created_at":"2014-08-06T21:38:41.000Z","updated_at":"2014-08-06T21:38:41.000Z"},{"id":2,"name":"Blues","created_at":"2014-08-06T21:38:53.000Z","updated_at":"2014-08-06T21:38:53.000Z"},{"id":3,"name":"Greens","created_at":"2014-08-06T21:39:03.000Z","updated_at":"2014-08-06T21:39:03.000Z"}]);
  });

和我的控制器:

app.controller('ProductsIndexCtrl', ['$scope', 'ColorGroup', 'Shape', 'Material', function($scope, ColorGroup, Shape, Material) {
  ColorGroup.query().$promise.then(function(data) {
    $scope.color_groups = data;
  });

发生了什么事?如何匹配对象数组?控制台中的输出甚至显示它们匹配! toEqual 不工作。

【问题讨论】:

    标签: angularjs jasmine


    【解决方案1】:

    我想出了一个使用JSON.stringify();的解决方法

    expect(JSON.stringify(scope.color_groups)).toEqual(JSON.stringify([{"id":1,"name":"Browns","created_at":"2014-08-06T21:38:41.000Z","updated_at":"2014-08-06T21:38:41.000Z"},{"id":2,"name":"Blues","created_at":"2014-08-06T21:38:53.000Z","updated_at":"2014-08-06T21:38:53.000Z"},{"id":3,"name":"Greens","created_at":"2014-08-06T21:39:03.000Z","updated_at":"2014-08-06T21:39:03.000Z"}]));
    

    【讨论】:

    【解决方案2】:

    面临同样的问题。我发现这个解释很有用,它解决了我的问题。

    AngularJS + Jasmine: Comparing objects

    [toEqual 进行深度相等比较。这意味着当对象的所有属性的值都相等时,对象被认为是相等的。

    如您所说,您使用的资源会为数组中的对象添加几个属性。

    所以这个 {id:12} 变成了这个 {id:12, $then: function, $resolved: true} ,它们不相等。如果您只是测试是否正确设置了值,则 ID 检查应该没问题。 ]1

    【讨论】:

      最近更新 更多