繁体   English   中英

如何让mocha在断言错误中显示diff中的整个对象?

[英]How to have mocha show entire object in diff on assertion error?

我有一个使用mocha和chai创建的单元测试测试用例,我希望将一组值对象与JSON文件的已解析内容进行深度比较。

我的记录对象有大约20个属性,目前只有价格可能导致不匹配。 在差异上,我只看到其中的五个。

 expect(records).to.deep.equal(expected);

       "data": {
  -      "price": 3578
  +      "price": 3438
         "not_important": "foo"
         "also_not_important": "bar"
       }
       "data": {
  -      "price": 1828
  +      "price": 1698
         "not_important": "foo"
         "also_not_important": "bar"
       }

在大多数情况下,这是非常有用的默认值,但在这一情况下,它会混淆哪个特定数据对象正在破坏断言,因为我在这里只看到冗余数据。

假设数据对象中有一个important属性可以清楚地表明什么样的期望会破坏测试。 因此,我希望能够配置显示的属性或在diff中显示整个对象。

如何配置mocha的diff显示?


这是一个展示问题的设计元语法示例:

import {expect} from "chai";

describe(("diff problem"), () => {
    it("should show case that the diff is not shown properly", () => {
        const actual = {
            a: 1,
            troiz: 0,
            bar: 0,
            baz: 2,
            poit: 3,
            narf: 4,
            fizzbuzz: 117,
            fizz: 5,
            buzz: 4,
            waldo: 115,
            mos: 85465,
            important: "THIS IS IMPORTANT",
        };

        const expected = {
            ...actual,
            a: 0,
        };

        return expect(actual).to.deep.equal(expected);
    });
});

该测试用例的输出将是:

2)SourceParser diff问题应该在一个属性的错误上显示整个diff:

  AssertionError: expected { Object (a, troiz, ...) } to deeply equal { Object (a, troiz, ...) }
  + expected - actual

   {
  -  "a": 1
  +  "a": 0
     "bar": 0
     "baz": 2
     "buzz": 4
     "fizz": 5

然而, important: "THIS IS IMPORTANT" ,这将是有益的。


以下是数组大小写的修改示例:

describe(("diff problem with an array"), () => {
    it("should show case that the diff is not shown properly for deep equal of arrays", () => {
        const anEntity = {
            a: 1,
            troiz: 0,
            bar: 0,
            baz: 2,
            poit: 3,
            narf: 4,
            fizzbuzz: 117,
            fizz: 5,
            buzz: 4,
            waldo: 115,
            mos: 85465,
            important: "IMPORTANT", // assume that each item has a unique important property, which is why it's helpful for it to be shown
        };

        const offendingItem = {
            ...anEntity,
            a: 0,
        };

        const actual = [
            anEntity,
            offendingItem,
            anEntity,
        ];

        const expected = [
            anEntity,
            anEntity,
            anEntity,
        ];

        return expect(actual).to.deep.equal(expected);
    });

输出将是:

  AssertionError: expected [ Array(3) ] to deeply equal [ Array(3) ]
  + expected - actual

       "troiz": 0
       "waldo": 115
     }
     {
  -    "a": 0
  +    "a": 1
       "bar": 0
       "baz": 2
       "buzz": 4
       "fizz": 5

路易斯的答案修改chai会变得更好,因为它只会首先转储整个实际数组然后显示无用的差异:

AssertionError: expected [ { a: 1,
    troiz: 0,
    bar: 0,
    baz: 2,
    poit: 3,
    narf: 4,
    fizzbuzz: 117,
    fizz: 5,
    buzz: 4,
    waldo: 115,
    mos: 85465,
    important: 'IMPORTANT' },
  { a: 0,
    troiz: 0,
    bar: 0,
    baz: 2,
    poit: 3,
    narf: 4,
    fizzbuzz: 117,
    fizz: 5,
    buzz: 4,
    waldo: 115,
    mos: 85465,
    important: 'IMPORTANT' },
  { a: 1,
    troiz: 0,
    bar: 0,
    baz: 2,
    poit: 3,
    narf: 4,
    fizzbuzz: 117,
    fizz: 5,
    buzz: 4,
    waldo: 115,
    mos: 85465,
    important: 'IMPORTANT' } ] to deeply equal [ { a: 1,
    troiz: 0,
    bar: 0,
    baz: 2,
    poit: 3,
    narf: 4,
    fizzbuzz: 117,
    fizz: 5,
    buzz: 4,
    waldo: 115,
    mos: 85465,
    important: 'IMPORTANT' },
  { a: 1,
    troiz: 0,
    bar: 0,
    baz: 2,
    poit: 3,
    narf: 4,
    fizzbuzz: 117,
    fizz: 5,
    buzz: 4,
    waldo: 115,
    mos: 85465,
    important: 'IMPORTANT' },
  { a: 1,
    troiz: 0,
    bar: 0,
    baz: 2,
    poit: 3,
    narf: 4,
    fizzbuzz: 117,
    fizz: 5,
    buzz: 4,
    waldo: 115,
    mos: 85465,
    important: 'IMPORTANT' } ]
      + expected - actual

           "troiz": 0
           "waldo": 115
         }
         {
      -    "a": 0
      +    "a": 1
           "bar": 0
           "baz": 2
           "buzz": 4
           "fizz": 5

据我所知,没有内置的方式来获得柴或摩卡产生差异列表,将添加到由DIFF一些领域是不负责的测试失败提供的上下文。 而且我不知道任何扩展正是您正在寻找的。 所以我只知道解决方法。


如果将truncateThreshold配置设置为较大的值,或者如果不想要任何截断,则设置为0 ,diff之前显示的失败消息将显示整个对象。 所以,如果我将其添加到您的代码中:

chai.config.truncateThreshold = 0; // 0 means "don't truncate, ever".

(本文档页面介绍了配置选项。)

然后我得到的错误是:

      AssertionError: expected { a: 1,
  troiz: 0,
  bar: 0,
  baz: 2,
  poit: 3,
  narf: 4,
  fizzbuzz: 117,
  fizz: 5,
  buzz: 4,
  waldo: 115,
  mos: 85465,
  important: 'THIS IS IMPORTANT' } to deeply equal { a: 0,
  troiz: 0,
  bar: 0,
  baz: 2,
  poit: 3,
  narf: 4,
  fizzbuzz: 117,
  fizz: 5,
  buzz: 4,
  waldo: 115,
  mos: 85465,
  important: 'THIS IS IMPORTANT' }
      + expected - actual

       {
      -  "a": 1
      +  "a": 0
         "bar": 0
         "baz": 2
         "buzz": 4
         "fizz": 5

此外,在错误消息中获取自定义信息的方法是使用断言设置自定义消息,例如:

expect(actual).to.deep.equal(
            expected,
            `failed equality test on object with important field set to: ${actual.important}`)

自定义消息可以像您需要的那样详细或简洁。

如果只有一个字段对于区分对象很重要,则自定义消息可能足以获取跟踪问题所需的信息。


对于对象数组,您可以通过迭代actualexpected数组并比较每个成员来执行比较。 然后它基本上如上所述地起作用。 当然,这有一个缺点:例如,如果第1项和第10项不同,您将只获得第1项的报告,因为测试将以该比较失败结束。 当您解决此问题并再次运行测试时,您将获得项目10的报告。实际上这是否是一个主要问题取决于您正在测试的数据类型。


我在默认diff算法没有按照我想要的方式做的一件事就是导入一个我喜欢配置的差异库,然后使用库在我关心的对象之间执行差异并组合结果进入最终报告,然后用断言检查。

同样,我不知道有一个库可以专门用于你正在寻找的东西。 但是,我可以想象迭代actualexpected数组,每对产生一个差异报告,然后将它们组合成一个包含识别信息的更大报告。

您可以在mocha命令中添加--inline-diffs ,它将显示整个对象的行号和内联差异:

mocha --inline-diffs YourSpec.js

文档有点误导: https//mochajs.org/#diffs

摩卡结果

注意由于所有的downvotes:我是OP。 我的预期解决方案不是解决我的架构决策的实际问题。 拥有比较大型对象的解决方案是一种代码味道。 我重构了我的代码库,以便我不再需要这个尝试过的解决方案了。


你正试图解决错误的问题。 您的预期解决方案只是一种解决方法。

你的实际问题是依靠深入比较一大堆巨大的物体开始。

您应该重构您的代码库,以便通过价格计算服务进行价格计算。 通过简单的断言对单个测试服务很简单。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM