首页 > 解决方案 > 将字符串与对象属性的深层嵌套字符串值进行比较的最佳方法?

问题描述

我正在为一个函数编写测试,我遇到了一个问题。我可以乱七八糟地实现我想要的,但我想让它更有活力。

例如,如果我有,

import { mapValues, isObject, forIn } from 'lodash';

const trimText = field => typeof field === 'string' ? field.replace(/^\s+|\s+$/g, '') : field;

const trimFields: any = data => mapValues(data, (element, k) => isObject(element) ? trimFields(element) : trimText(element));

const simpleObject = {
  fieldA: [' simple trim ', 'simple trim'],
  fieldB: [' new\n   line trim ', 'new\n   line trim'],
  fieldC: [' \n\ts\n\t\n ', 's']
};

我可以为它写一个测试,

describe('Simple object /', () => {
  const objectToTrim: any = {};
  forIn(simpleObject, ([raw], key) => {
    objectToTrim[key] = raw;
  });

  const trimmedObject = trimFields(objectToTrim);
  forIn(trimmedObject, (value, key) => {
    it(`Should have properly trimmed ${value} into ${simpleObject[key][1]}`, () => {
      expect(value).toEqual(simpleObject[key][1]);
    });
  });
});

但是现在,我遇到了一个复杂对象的问题。例如,如果我有:

const complexObject: any = {
  fieldA: [
    { subfieldA: ' simple trim ' },
    'simple trim'
  ],
  fieldB: [
    {
      subfieldB: {
        subSubFieldB: ' new\n   line trim '
      }
    },
    'new\n   line trim'
  ],
  fieldC: [
    {
      subfieldC: {
        subSubFieldC: {
          subSubSubfieldC: ' \n\ts\n\t\n '
        }
      }
    },
    's'
  ]
};

我不确定如何测试这个。有没有办法编写与简单对象相同的测试,但是通过某种方式找到嵌套值?例如,使用 lodash(因为无论如何我已经在使用它了),是否可以找到subSubSubfieldCinfieldC然后将其与我在withcomplexObject[key][1]中所做的比较?expect(...)simpleObject[key][1]

标签: javascriptreactjsjestjs

解决方案


您可以使用 Jest 的 it.each 来提供不同的输入(避免使用 lodash)来提供对象中的不同路径并.toHaveProperty匹配路径和值

示例(未测试):

describe('Complex object', () => {
  let result;
  beforeAll(() => {
    result = trimFields({
      fieldA: [
        { subfieldA: ' simple trim ' },
        'simple trim'
      ],
      fieldB: [
        {
          subfieldB: {
            subSubFieldB: ' new\n   line trim '
          }
        },
        'new\n   line trim'
      ],
      fieldC: [
        {
          subfieldC: {
            subSubFieldC: {
              subSubSubfieldC: ' \n\ts\n\t\n '
            }
          }
        },
        's'
      ]
    })
  })

  it.each([
    ['fieldA.0.subfieldA', 'simple trim'],
    ['fieldA.1', 'simple trim'],
    ['fieldB.0.subfieldB.subSubFieldB', 'new line trim']
  ])('should have property %s with trimmed value %s', (path, value) => {
    expect(result).toHaveProperty(path, value);
  })
})

推荐阅读