【问题标题】:I'm trying to test a function that takes another function as a parameter我正在尝试测试一个将另一个函数作为参数的函数
【发布时间】:2020-02-03 15:57:31
【问题描述】:

我正在使用 chai 尝试对我在网上找到的验证功能进行单元测试。此验证功能正在“react-final-form”组件内部使用。

这是我从这里得到这个验证器函数的地方:

https://youtu.be/OEg8jm-NbQ0?t=567

import chai, { expect } from "chai";
import chaiEnzyme from "chai-enzyme";

chai.use(chaiEnzyme());

const required = (value) => value === '' ? 'This is required.' : undefined;
const url = (value) => value && !(/^\/[a-z0-9]+$|[-a-zA-Z0-9@:%_\+.~#?&//=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?/gi).test(value) ? 'This does not appear to be a link.': undefined;

const composeValidators = (...validators) => 
  (value) => 
    validators.reduce((error, validator) => error || validator(value), undefined);

let value = '';

describe("Forms", () => {
  describe("Final form", () => {
    describe("Utils", () => {
      it("Returns correct error message when form field value is empty and field is required", () => {
        expect(composeValidators(required)).to.equal('This is required.');
      });

      it("Returns correct error message when form field value is not empty and field should be a url", () => {
        value = 'not empty';
        expect(composeValidators(url)).to.equal('This does not appear to be a link.');
      });
    });
  });
});

目前这两个断言都返回 [function] 而不是我期望的字符串值,我不知道为什么。任何有关如何修复此测试的想法将不胜感激。

【问题讨论】:

  • 看起来url 是一个函数的引用,我想你需要调用composeValidators(url(value))composeValidators(required("some value?"))
  • 我试过这样做,遗憾的是两个函数仍然返回 [function]
  • 还有其他人的想法吗?
  • composeValidators(required, url, ...)("").to.equal("This is required")composeValidators(required, url, ...)("https://*.com").to.equal(undefined) - 切勿使用您不理解的代码。

标签: javascript functional-programming tdd enzyme chai


【解决方案1】:

我确实喜欢最终形式。它确实有助于深入了解如何使用柯里化函数。所以,你从我个人使用的最终表单中获取的示例与字段。

composeValidators(required)(value)

Currying 是一个奇怪的概念,你不需要它就可以理解它,所以不要担心乍一看不理解它。

我们来看看签名:

const composeValidators = (...validators) => (value) =>

第一个函数接受 X 个道具或验证规则。你已经把那部分记下来了。现在,第二个函数需要一个值。您可能看到它与 Field 的 validate 道具一起使用。如果您查看 FieldProps 的文档(请参阅下面的链接),您会看到它接受一个函数并向其传递 3 个参数,即 value、allValues 和 meta,而不仅仅是 value。这可以帮助您编写更好的验证规则,以考虑有关该字段的更多信息。无论如何,当 final-form 使用它时,它采用以下形式:

composeValidators(required)(value, allValues, meta)

我不认为这会立即有意义,但它应该可以帮助您考虑一个特定的柯里化用例有一些高级选项。享受最终形式!

https://final-form.org/docs/react-final-form/types/FieldProps

【讨论】: