typescript - fp-ts 和 Jest : ergonomic tests for Option and Either?

标签 typescript testing jestjs fp-ts

我正在使用 fp-ts,并使用 Jest 编写单元测试。在许多情况下,我正在测试可为 null 的结果,通常用 OptionEither 表示(通常是数组 find)。如果结果为none(以Option为例),并且继续知道这个结果是some,最符合人体工程学的方法是什么?

以下是我目前如何解决问题的示例:

function someFunc(input: string): Option.Option<string> {
  return Option.some(input);
}

describe(`Some suite`, () => {
  it(`should do something with a "some" result`, () => {
    const result = someFunc('abcd');

    // This is a fail case, here I'm expecting result to be Some
    if(Option.isNone(result)) {
      expect(Option.isSome(result)).toEqual(true);
      return;
    }

    expect(result.value).toEqual('abcd');
  });
});

但是必须编写一个提前返回的 if 不太符合人体工程学。

我也可以编写一个 as 断言:

  // ...
  it(`should do something with a "some" result`, () => {
    const result = someFunc('abcd') as Option.Some<string>;

    expect(result.value).toEqual('abcd');
  });
  // ...

但缺点是我必须重写 some 的类型。在很多情况下,编写它很繁重,需要编写并导出接口(interface)以进行测试(这也不符合人体工程学)。

有什么办法可以简化这种测试吗?

编辑:这是一个更接近实际情况的测试用例:


interface SomeComplexType {
  id: string,
  inputAsArray: string[],
  input: string;
}

function someFunc(input: string): Option.Option<SomeComplexType> {
  return Option.some({
    id: '5',
    inputAsArray: input.split(''),
    input,
  });
}

describe(`Some suite`, () => {
  it(`should do something with a "some" result`, () => {
    const result = someFunc('abcd');

    // This is the un-ergonomic step
    if(Option.isNone(result)) {
      expect(Option.isSome(result)).toEqual(true);
      return;
    }

    // Ideally, I would only need this:
    expect(Option.isSome(result)).toEqual(true);
    // Since nothing will be ran after it if the result is not "some"
    // But I can imagine it's unlikely that TS could figure that out from Jest expects

    // Since I now have the value's actual type, I can do a lot with it
    // I don't have to check it for nullability, and I don't have to write its type
    const myValue = result.value;

    expect(myValue.inputAsArray).toEqual(expect.arrayContaining(['a', 'b', 'c', 'd']));

    const someOtherThing = getTheOtherThing(myValue.id);

    expect(someOtherThing).toMatchObject({
      another: 'thing',
    });
  });
});

最佳答案

您可以编写不安全的转换fromSome,如下所示:

function fromSome<T>(input: Option.Option<T>): T {
  if (Option.isNone(input)) {
    throw new Error();
  }
  return input.value;
}

然后在测试中使用它

  it(`should do something with a "some" result`, () => {
    const result = someFunc('abcd');
    const myValue = fromSome(result);
    // do something with myValue
  });

关于typescript - fp-ts 和 Jest : ergonomic tests for Option and Either?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59630012/

相关文章:

javascript - Window.Print 不会产生与使用浏览器打印功能相同的结果

javascript - Framer Motion "repeatType"属性导致类型错误

angular - 可观察类型数组

javascript - 如何使用 Jest 模拟 native javascript 方法?

Firebase 云功能单元测试 HTTP onCall

reactjs - 键入针对滚动条的 React useRef

c# - 如何对与串口接口(interface)的软件进行集成测试?

c - 在嵌入式和非嵌入式代码之间维护单一代码库

ruby-on-rails - rspec 国际化测试 View ?

jestjs - 找不到 Nestjs 测试模块