【问题标题】:Match partial objects in Chai assertions?匹配 Chai 断言中的部分对象?
【发布时间】:2015-04-09 08:00:13
【问题描述】:

我正在寻找匹配以下内容的最佳方式:

expect([
    {
        C1: 'xxx',
        C0: 'this causes it not to match.'
    }
]).to.deep.include.members([
    {
        C1: 'xxx'
    }
]);

上述不起作用,因为 C0 存在于实际中,但不是预期的。简而言之,我希望这个期望通过,但如果不编写一堆自定义代码,我不知道该怎么做......

【问题讨论】:

    标签: chai


    【解决方案1】:

    chai-subsetchai-fuzzy 也可能会执行您正在寻找的内容。

    Chai-subset 应该像这样工作:

    expect([
      {
        C1: 'xxx',
        C0: 'this causes it not to match.'
      }
    ]).to.containSubset([{C1: 'xxx'}]);
    

    如果我不想包含另一个插件,我将使用 chai 包含的 propertykeys 匹配器:

    ([
      {
        C1: 'xxx',
        C0: 'this causes it not to match.'
      }
    ]).forEach(obj => {
      expect(obj).to.have.key('C1'); // or...
      expect(obj).to.have.property('C1', 'xxx');
    });
    

    【讨论】:

      【解决方案2】:

      有几个不同的 chai 插件都可以解决这个问题。我是shallow-deep-equal 的粉丝。你可以这样使用它:

      expect([
          {
            C1: 'xxx',
            C0: 'this causes it not to match.'
          }
        ]).to.shallowDeepEqual([
          {
            C1: 'xxx'
          }
        ]);
      

      【讨论】:

      • 大声笑,那么浅或深相等?
      【解决方案3】:

      没有插件: http://chaijs.com/api/bdd/#method_property

        expect([
          {
            C1: 'xxx',
            C0: 'this causes it not to match.'
          }
        ]).to.have.deep.property('[0].C1', 'xxx');
      

      【讨论】:

        【解决方案4】:

        干净、实用且无依赖

        只需使用地图过滤您要检查的键

        类似:

        const array = [
            {
                C1: 'xxx',
                C0: 'this causes it not to match.'
            }
        ];
        
        expect(array.map(e=>e.C1)).to.include("xxx");
        

        https://www.chaijs.com/api/bdd/

        【讨论】:

        • 这取决于您的测试代码(映射函数)是否正确,并且可能必须测试您的测试代码......这不是最好的解决方案。
        • @Pureferret 我认为我们可以假设本机“地图”功能无需测试即可安全使用。至少它比使用外部库的风险要小得多。
        • 我并不怀疑本机功能是安全的,我 a) 强调对测试数据进行了一些修改,感觉很糟糕,b) 你需要确保无论你'打电话来获取测试数据总是正确的(即它必须知道C1)。当它被假设提取到测试辅助函数时会发生什么,并且不再清楚它在这个测试中做了什么。这是楔子的薄边。
        • 例如如果它最终被重构为expect(getC1(array)).to.include("xxx");,你必须相信'getC1'才能工作。
        • @Pureferret 理论上是的,但在现实生活中,如果您访问一级密钥,那就有点过头了。为避免错误,您可以将密钥放入变量中,然后稍后调用该变量,即const keyToTest = 'C1';。这里的其他答案提供安装一个库,这更加危险和反模式!编码是由妥协组成的,所以请“常识优先”。
        【解决方案5】:

        我相信最简单(当然也是最简单)的方法是:

        var actual=[
          {
            C1:'xxx',
            C0:'yyy'
          }
        ];
        
        actual.forEach(function(obj){
          expect(obj).to.have.property('C1','xxx');
        });
        

        【讨论】:

          【解决方案6】:

          您可以使用pickomit 下划线函数来选择/拒绝要测试的属性:

          const { pick, omit } = require('underscore');
          
          const obj = {
            C1: 'xxx',
            C0: 'this causes it not to match.',
          };
          
          it('tests sparse object with pick', () => {
            expect(pick(obj, 'C1')).to.eql({ C1: 'xxx' });
          });
          
          it('tests sparse object with omit', () => {
            expect(omit(obj, 'C0')).to.eql({ C1: 'xxx' });
          });
          

          【讨论】:

            【解决方案7】:

            我编写了chai-match-patternlodash-match-pattern 来处理部分匹配(以及更多)深度匹配场景。

            var chai = require('chai');
            var chaiMatchPattern = require('chai-match-pattern');
            chai.use(chaiMatchPattern);
            
            // Using JDON pattern in expectation
            chai.expect([
              {
                C1: 'xxx',
                C0: 'this causes it not to match.'
              }
            ]).to.matchPattern([
              {
                C1: 'xxx',
                '...': ''
              }
            ]);
            
            // Using the slightly cleaner string pattern notation in expectation
            chai.expect([
              {
                C1: 'xxx',
                C0: 'this causes it not to match.'
              }
            ]).to.matchPattern(`
              [
                {
                  C1: 'xxx',
                  ...
                }
              ]
              `
            );
            

            【讨论】:

              【解决方案8】:

              #RobRaisch 的略微更新版本,因为对于空比较给出错误,因为 '' 不等于 ""

              let expected = {
                          dateOfBirth: '',
                          admissionDate: '',
                          dischargeDate: '',
                          incidentLocation: null
                      };
                      Object.keys(expected).forEach(function(key) {
                          expect(actual[key]).to.equal(expected[key]);
                      });
              

              【讨论】:

                【解决方案9】:

                如果您需要将其与 spycall.with 一起使用,请查看此答案:https://stackoverflow.com/a/58940221/1151741

                例如

                expect(spy1).to.have.been.called.with.objectContaining({ a: 1 });
                

                【讨论】:

                  猜你喜欢
                  • 2016-01-05
                  • 2023-04-02
                  • 1970-01-01
                  • 1970-01-01
                  • 2013-06-03
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多