Сбой теста из-за .map не является ошибкой функции - PullRequest
0 голосов
/ 13 декабря 2018

Привет, у меня есть компонент реагирования cost-total.js и соответствующий контрольный пример cost-total.test.js , как показано ниже.

cost-total.js

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

cost-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 голосов
/ 13 декабря 2018

Проблема с if (expenses.length === 0), и в тестовом примере, использующем selectExpensesTotal(expenses[0]):

expenses[0], передается объект, у которого нет свойства length, поэтому в тестируемой функции expenses.length возвращает undefined.Однако undefined === 0 оценивается как false, поэтому ваш код попадает в блок else, пытаясь использовать .map для объекта, который не имеет этой функции, поэтому он выдает ошибку.

0 голосов
/ 13 декабря 2018

Проблема в том, что cost [0] - это объект (вы, вероятно, ожидали, что он будет массивом), а у объекта нет функции map.Быстрый взлом - добавить еще один if в цикл, чтобы проверить, действительно ли расходы являются объектом.Так что:

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);
    }
  }
};

Надеюсь, это поможет.

0 голосов
/ 13 декабря 2018

Вкратце: вы не можете отобразить объект .

expenses - это массив объектов, поэтому expenses[0] - это объект.

Условие expenses.length === 0 оценивается как false, поскольку, очевидно, .length свойство не существует в Object.prototype, поэтому имеет место условие else - ваша функция пытается map над объектом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...