在单元测试中,如何测试具有对象参数的功能?

时间:2018-12-07 07:55:06

标签: javascript reactjs unit-testing testing jestjs

进行单元测试时,是否必须发送完整的真实对象参数? 还是只发送一个对象参数,其中包含该函数所需的属性?

例如,这是一个需要单元测试的示例函数:

    function ChangeName(person) {
      if (person !== null) {
        let {firstName} = person.firstName;
        firstName = firstName + '_firstName';
        person.firstName = firstName;
        return person;
      }
      return person;
    }

以下是发送完整对象的示例测试:

    expect(
      ChangeName(
        {
          firstName: 'Juan', 
          lastName: 'dela Cruz', 
          age: 22, 
          gender: 'Male', 
          aboutMe: 'About_Me', 
          schools:[
            {id: 1, name: 'School Name 1'},
            {id: 1, name: 'School Name 1'},
            {id: 1, name: 'School Name 1'},
            {id: 1, name: 'School Name 1'}
          ]
        }
      )
    ).toEqual(
      {
        firstName: 'Juan_firstName', 
        lastName: 'dela Cruz', 
        age: 22, 
        gender: 'Male', 
        aboutMe: 'About_Me', 
        schools:[
          {id: 1, name: 'School Name 1'},
          {id: 1, name: 'School Name 1'},
          {id: 1, name: 'School Name 1'},
          {id: 1, name: 'School Name 1'}
        ]
      }
    );

这里是一个示例测试,它发送一个对象,该对象具有仅在函数中需要的属性(包括用于示例的lastName):

    expect(
      ChangeName(
        {
          firstName: 'Juan', 
          lastName: 'dela Cruz', 
        }
      )
    ).toEqual(
      {
        firstName: 'Juan_firstName', 
        lastName: 'dela Cruz', 
      }
    );

2 个答案:

答案 0 :(得分:1)

我只提供需要测试的代码。

对于您而言,这意味着:

expect(changeName({ 
    firstName: 'Juan',
    lastName: 'dela Cruz'
}).toEqual({ 
    firstName: 'Juan_firstName',
    lastName: 'dela Cruz'
});

为什么?

  • 重构人员对象时工作量少
  • 测试更具可读性,您只有测试关注的内容
  • 通过鸭子输入和/或功能编程,您可以在其他对象(宠物...)上重用此功能
  • lastName(或任何其他名称)明确表明,其他任何内容都不应更改

如果您使用打字(流,打字稿),这可能会改变。


我还注意到了一些可能会打扰您的错误:

let { firstName } = person;

您不必重复名字

const newPerson = {
    ...person,
    firstName: firstName + '_firstName'
}
return newPerson;

这样,您就不会变异原始人对象,这可能会对React有害。

答案 1 :(得分:0)

这取决于您希望测试提供的保证。

在您的示例中,如果唯一要检查的是“ firstName属性已按预期更新”,则{ firstName: 'Juan' }是传递给{{1 }}功能。

但是,如果您的测试需要提供的保证实际上是“ changeName属性已按预期进行了更新,并且没有其他更改”,那么拥有完整的对象,代表该函数期望处理的数据类型。

如果如测试示例中所示实施,则后者可能更难阅读。可以通过将对象创建放在实用工具函数中来减轻这种情况,在这种情况下,它可以像更简单的示例一样可读。

firstName