【问题标题】:Jest test fails if using Ramda reduce but passes with native如果使用 Ramda reduce,Jest 测试会失败,但使用 native 会通过
【发布时间】:2017-09-12 14:52:36
【问题描述】:

我注意到,如果我使用ramda,有时我会在尝试为我正在导出的方法编写Jest 测试时遇到问题。我将问题归结为以下测试和两个基本的减速器功能。我已将它们发布在 gist 上,以免代码堵塞这个问题。

https://gist.github.com/beardedtim/99aabe3b08ba58037b20d65343ed9d20

ramda 减速器出现以下错误:

      ● counter usage › counter counts the words and their index in the given list of words

    expect(received).toEqual(expected)

    Expected value to equal:
      [{"count": 3, "indexes": [0, 2, 4], "value": "a"}, {"count": 1, "indexes": [1], "value": "b"}, {"count": 1, "indexes": [3], "value": "c"}]
    Received:
      [{"count": 15, "indexes": [0, 2, 4, 0, 2, 4, 0, 2, 4, 0, 2, 4, 0, 2, 4], "value": "a"}, {"count": 5, "indexes": [1, 1, 1, 1, 1], "value": "b"}, {"count": 5, "indexes": [3, 3, 3, 3, 3
], "value": "c"}]

这让我相信ramda 的reduce 是保持某种状态或彼此共享words。我不确定这是怎么发生的。有人知道我应该在谷歌上搜索什么或其他处理此问题的一些文档/示例吗?

【问题讨论】:

  • 这看起来像是数组reduce 的实现github.com/ramda/ramda/blob/master/src/internal/…
  • @elclanrs 感谢您指出reduce 没有索引。添加索引不会改变我的测试由于某种原因仍然失败。我已经更新了要点以反映这一点。

标签: javascript unit-testing jestjs ramda.js babel-jest


【解决方案1】:

状态数组 (final) 硬连线到 reduceWithIndex。对该函数的所有调用共享同一个final 数组。

试试这个:

import { reduce, addIndex } from 'ramda';

const reduceWithIndex = addIndex(reduce)((final, word, index) => {
  const found = final.find(({ value }) =>
    value.toLowerCase() === word.toLowerCase()
  );
  if (found) {
    found.count++;
    found.indexes.push(index);
  } else {
    final.push({
      value: word.toLocaleLowerCase(),
      count: 1,
      indexes: [index],
    });
  }

  return final;
});

export default words => reduceWithIndex([], words);

【讨论】:

    【解决方案2】:

    Thomas 的诊断非常准确。但我会选择稍微不同的解决方法:

    import { reduce, addIndex, append } from 'ramda';
    
    const reduceWithIndex = addIndex(reduce);
    
    export default reduceWithIndex((final, word, index) => {
      const found = final.find(({ value }) =>
        value.toLowerCase() === word.toLowerCase()
      );
      if (found) {
        found.count++;
        found.indexes.push(index);
        return final;
      }
      return append({
          value: word.toLocaleLowerCase(),
          count: 1,
          indexes: [index],
      }, final);
    }, []);
    

    函数式编程涉及很多方面,但其中最重要的一项是不可变数据结构。尽管没有什么可以阻止您改变累加器对象并将其传递回减速器函数,但我发现它的风格很差。相反,总是返回一个新对象,你就不会遇到这样的问题。 Ramda 的所有功能都是建立在这个原理上的,所以在使用append 时,会自动得到一个新的列表。

    我还建议更改if-block 以避免found 对象的内部突变。我将把它留作练习,但如果很难做到,请随时 ping。

    您可以在 Ramda REPL 中看到 original solutionaltered version 之间的区别。

    【讨论】:

      猜你喜欢
      • 2021-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-17
      • 1970-01-01
      • 1970-01-01
      • 2022-08-14
      • 1970-01-01
      相关资源
      最近更新 更多