【问题标题】:How to test complex tree structure?如何测试复杂的树结构?
【发布时间】:2021-07-06 01:52:55
【问题描述】:

Jasmine 支持注册custom equality tester。这在 Jest 中可能吗?如果没有,我该如何测试以下内容:

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

// This API does not exist :(
expect.addCustomEqualityTester((first, second) => {
  if (first instanceof Person && second instanceof Person) {
    // Only name is important
    return first.name === second.name;
  }
});

// This array can be arbitrarily complex with many different objects and nestings.
// It's a tree structure.
expect(got).toEqual([
  new Person('Alice', 10),
  new Person('Bob', 20),
  new Foo(a, b, c),
  [
    new Person('Emma', 5),
    [x, y, z],
    new Person('Troy', 25),
  ],
]);

我知道我可以使用expect.extend 为单个对象添加自定义匹配器,但是在上述对象架构非常动态的情况下,我将如何使用它?

有一个 GitHub issue 请求这个确切的 API,但它在没有解决这个问题的情况下被关闭,所以现在我只是困惑这个库如何如此受欢迎并且没有人有这个问题。也许这是一个 XY 问题?

【问题讨论】:

  • 这能回答你的问题吗? Custom matcher in jest
  • 没有。我已经提到我了解expect.extend API,但在这种情况下它不起作用,因为我的自定义匹配器不适用于进行深度相等检查的toEqual
  • 您的“对象架构非常动态”异常听起来很可疑,就像您想要一个可以读懂您的想法的匹配器。解决方案很明显:您必须编写一个匹配器,根据您的自定义逻辑解包传递的值,并且它只能支持您能够在 javascript 中编码的比较。
  • 我提供的 sn-p 在 Jasmine 中完美运行,但在 Jest 中没有等效的 API。你是说我必须实现类似toEqualCustom 的东西,它与toEqual 做同样的事情,除了支持为它在遍历期间看到的某些对象添加自定义相等检查?

标签: javascript unit-testing jestjs


【解决方案1】:

我通过创建一个新的toEqualCustom 匹配器解决了我的问题,它与现有的toEqual 匹配器基本相同,只是它支持传入自定义测试器。匹配器中可用的equals 实用函数支持自定义测试器。

expect.extend({
  toEqualCustom(received, expected, customTesters) {
    const options = {
      comment: 'Deep object equality with custom equality testers',
      isNot: this.isNot,
      promise: this.promise,
    };

    const pass = this.equals(received, expected, customTesters);

    const message = () =>
      this.utils.matcherHint('toEqualCustom', undefined, undefined, options) +
      '\n\n' +
      `Expected: ${this.isNot ? 'not' : ''} ${this.utils.printExpected(expected)}\n` +
      `Received: ${this.utils.printReceived(received)}`;

    return {
      actual: received,
      message,
      pass,
    };
  },
});

function personNameTester(a, b) {
  if (a instanceof Person && b instanceof Person) {
    return a.name === b.name;
  }
}

expect(foo).toEqualCustom(bar, [personNameTester]);

但是,与此相关的一个问题是,为失败的测试显示的差异并不总是正确的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-23
    • 1970-01-01
    • 2021-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多