在Jest测试用例上比较包含匿名函数的对象

Fel*_*rri 3 javascript jestjs react-native

我在ReactNative项目上开玩笑。我想在一个测试用例中比较两个相同类的对象。这是一个示例类定义:

class Person {
    constructor(id, name, lastName) {
        this.id = id;
        this.name = name;
        this.lastName = lastName;
    }       

    fullName = () => {
        return `${this.name} ${this.lastName}`;
    }
}
Run Code Online (Sandbox Code Playgroud)

我创建了一个测试用例,该用例比较了Person应该相同的类的两个对象:

test('checks the Person.constructor method', () => {
    expect(new Person(1, 'John', 'Smith')).toEqual(new Person(1, 'John', 'Smith'));
});
Run Code Online (Sandbox Code Playgroud)

但是我得到以下结果:

 FAIL  __tests__/Comparison-test.js (7.328s)
  ? checks the Person.constructor method

    expect(received).toEqual(expected)

    Expected: {"fullName": [Function anonymous], "id": 1, "lastName": "Smith", "name": "John"}
    Received: {"fullName": [Function anonymous], "id": 1, "lastName": "Smith", "name": "John"}

      48 | 
      49 | test('checks the Person.constructor method', () => {
    > 50 |     expect(new Person(1, 'John', 'Smith')).toEqual(new Person(1, 'John', 'Smith'));
         |                                            ^
      51 | });

      at Object.toEqual (__tests__/Comparison-test.js:50:44)
Run Code Online (Sandbox Code Playgroud)

比较期望值和接收值,可以从视觉上看到它们是相同的,但是由于匿名函数,我知道它们不相同fullName

如何比较两个对象?我希望能够不理会匿名函数,即使两个对象中的函数相同。

expect通过设置lastName为尝试使用该功能expect.anything()。下面的测试实际上通过了:

test('checks the Person.constructor method', () => {
    expect(new Person(1, 'John', 'Smith')).toEqual({
        id: 1,
        name: 'John',
        lastName: 'Smith',
        fullName: expect.anything()});
});
Run Code Online (Sandbox Code Playgroud)

但是,这并不是真正希望的,因为我必须列出要测试的类的所有功能,并且如果我向一个类添加更多功能,则所有测试都将中断。

那么,有没有一种方法可以在不考虑对象的所有功能的情况下比较同一类的两个对象呢?

谢谢!

Bri*_*ams 5

听起来像您想要的toMatchObject,它匹配“对象属性的子集”:

test('checks the Person.constructor method', () => {
  expect(new Person(1, 'John', 'Smith')).toMatchObject({
    id: 1,
    name: 'John',
    lastName: 'Smith'
  });  // Success!
});
Run Code Online (Sandbox Code Playgroud)

更新资料

OP在评论中询问是否仍然可以使用实例。

它还可以使用JSON.stringify并比较结果来序列化对象:

test('checks the Person.constructor method', () => {
  expect(JSON.stringify(new Person(1, 'John', 'Smith')))
    .toBe(JSON.stringify(new Person(1, 'John', 'Smith')));  // Success!
});
Run Code Online (Sandbox Code Playgroud)