.map导致的测试用例失败不是函数错误

时间:2018-12-12 22:26:19

标签: javascript arrays reactjs enzyme

嗨,我有一个react组件 expenses-total.js 和一个相应的测试用例 expenses-total.test.js ,如下所示。

expenses-total.js

     export default (expenses=[]) => {
      if (expenses.length === 0) {
        return 0;
      } else {
        return expenses
          .map(expense => expense.amount)
          .reduce((sum, val) => sum + val, 0);
      }
    };

expenses-total.test.js

import selectExpensesTotal from '../../selectors/expenses-total';
const expenses = [
    {
      id: "1",
      description: "gum",
      amount: 321,
      createdAt: 1000,
      note: ""
    },
    {
      id: "2",
      description: "rent",
      amount: 3212,
      createdAt: 4000,
      note: ""
    },
    {
      id: "3",
      description: "Coffee",
      amount: 3214,
      createdAt: 5000,
      note: ""
    }
  ];

test('Should return 0 if no expenses', ()=>{
    const res = selectExpensesTotal([]);
    expect(res).toBe(0);
});

test('Should correctly add up a single expense', ()=>{
    const res = selectExpensesTotal(expenses[0]);
    expect(res).toBe(321);
});

test('Should correctly add up multiple expenses',()=>{
    const res = selectExpensesTotal(expenses);
    expect(res).toBe(6747);
});

当我运行测试用例时,由于给出错误而失败

TypeError: expenses.map is not a function

我知道测试用例是正确的,但是不知道组件出了什么问题。 有人可以帮我解决此错误吗?

3 个答案:

答案 0 :(得分:2)

问题出在if (expenses.length === 0)和使用selectExpensesTotal(expenses[0])的测试用例中:

expenses[0]传递了一个没有length属性的对象,因此在被测试的函数中,expenses.length返回了undefined。但是,undefined === 0的计算结果为false,因此您的代码进入了else块,试图在不具有该功能的对象上使用.map,因此会抛出一个错误。

答案 1 :(得分:0)

简而言之:您不能在对象上进行映射

expenses是一个对象数组,所以expenses[0]是一个对象。

条件expenses.length === 0的计算结果为false,因为显然.length上的Object.prototype属性不存在,所以else条件发生-您的函数尝试在对象上map

答案 2 :(得分:0)

问题在于,费用[0]是一个对象(您可能希望它是一个数组),而一个对象没有地图功能。一个快速的技巧是在循环中添加另一个ifs,以检查费用是否实际上是一个对象。这样:

export default (expenses=[]) => {
  if (expenses.length === 0) {
    return 0;
  } else {
    if (typeof expenses === 'object') {
      return expenses.amount
    } else {
    return expenses
      .map(expense => expense.amount)
      .reduce((sum, val) => sum + val, 0);
    }
  }
};

我希望有帮助。