Kiểm tra bình đẳng đối tượng trong Jasmine


85

Jasmine có các trình kết hợp tích hợp toBetoEqual. Nếu tôi có một đối tượng như thế này:

function Money(amount, currency){
    this.amount = amount;
    this.currency = currency;

    this.sum = function (money){
        return new Money(200, "USD");
    }
}

và cố gắng so sánh new Money(200, "USD")và kết quả của tổng, những đối sánh tích hợp sẵn này sẽ không hoạt động như mong đợi. Tôi đã quản lý để triển khai một công việc xung quanh dựa trên một equalsphương pháp tùy chỉnh và trình đối sánh tùy chỉnh, nhưng nó dường như hoạt động nhiều.

Cách chuẩn để so sánh các đối tượng trong Jasmine là gì?

Câu trả lời:


172

Tôi đang tìm kiếm điều tương tự và đã tìm thấy một cách hiện có để làm điều đó mà không cần bất kỳ mã tùy chỉnh hoặc trình kết hợp nào. Sử dụng toEqual().


63

Nếu bạn đang muốn so sánh các đối tượng từng phần, bạn có thể cân nhắc:

describe("jasmine.objectContaining", function() {
  var foo;

  beforeEach(function() {
    foo = {
      a: 1,
      b: 2,
      bar: "baz"
    };
  });

  it("matches objects with the expect key/value pairs", function() {
    expect(foo).toEqual(jasmine.objectContaining({
      bar: "baz"
    }));
  });
});

cf. jasmine.github.io/partial-matching


3

Đó là hành vi mong đợi, vì hai trường hợp của một đối tượng không giống nhau trong JavaScript.

function Money(amount, currency){
  this.amount = amount;
  this.currency = currency;

  this.sum = function (money){
    return new Money(200, "USD");
  }
}

var a = new Money(200, "USD")
var b = a.sum();

console.log(a == b) //false
console.log(a === b) //false

Đối với một bài kiểm tra rõ ràng, bạn nên viết trình đối sánh của riêng mình để so sánh amountcurrency:

beforeEach(function() {
  this.addMatchers({
    sameAmountOfMoney: function(expected) {
      return this.actual.currency == expected.currency && this.actual.amount == expected.amount;
    }
  });
});

2

Tôi thấy rằng lodash _.isEqual là tốt cho điều đó

expect(_.isEqual(result, expectedResult)).toBeTruthy()

-4

Vấn đề của bạn là với tính trung thực. Bạn đang cố gắng so sánh hai trường hợp khác nhau của một đối tượng đúng với đẳng thức thông thường (a == b) nhưng không đúng với đẳng thức nghiêm ngặt (a === b). Phép so sánh mà hoa nhài sử dụng là jasmine.Env.equals_ () tìm kiếm sự bình đẳng nghiêm ngặt.

Để thực hiện những gì bạn cần mà không cần thay đổi mã của mình, bạn có thể sử dụng bình đẳng thông thường bằng cách kiểm tra tính trung thực bằng một số thứ như sau:

expect(money1.sum() == money2.sum()).toBeTruthy();

9
Những gì bạn nói về =====là hoàn toàn sai. Hai trường hợp khác nhau của một đối tượng có cùng nội dung sẽ trả về false. Đối với bất kỳ hành vi không phải nguyên thủy nào =====hoạt động giống hệt nhau. jsfiddle.net/9mrmyrs6
Juan Mendes

@JuanMendes kiểm tra câu trả lời của Andreas K. ... các bạn đang nói hai điều khác nhau. Đây có phải là sự khác biệt trong việc tạo mới một đối tượng so với một đối tượng theo nghĩa đen?
pherris

@pherris mmm .... vâng, chúng tôi đang nói những điều khác nhau: Tôi đang nói rằng khi so sánh những thứ không phải nguyên thủy, không quan trọng bạn có sử dụng ==hay không ===, không có sự ép buộc nào liên quan. Andreas đang nói rằng bạn có thể tạo một trình đối sánh tùy chỉnh. Tuyên bố cuối cùng về cách khắc phục sự cố này là "đúng" nhưng lời giải thích trong đoạn đầu tiên là không chính xác. jasminesẽ thực sự kiểm tra nội dung đối tượng nếu bạn sử dụng toBe()thay vìequals
Juan Mendes

a == bvẫn sẽ cung cấp cho false nếu abnhững trường khác nhau, bạn có thể muốn chỉnh sửa câu trả lời của bạn
Louie Almeda
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.