【发布时间】:2020-04-25 01:17:49
【问题描述】:
我正在使用fp-ts,并使用 Jest 编写单元测试。在许多情况下,我正在测试可为空的结果,通常用Option 或Either 表示(通常是数组finds)。如果结果为 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 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',
});
});
});
【问题讨论】:
-
我不确定我是否跟随。什么是有效案例?
Option.isNone(result)是true?还是什么? -
我已经更新了描述,希望能更清楚。这个测试用例假设结果应该是
some(根据函数的内容) -
expect(Option.isSome(result)).toEqual(true)? -
@Lee 这是一种解决方法,可以在运行测试时出现更好的错误。我确实期待
Option.isSome(result)是true,因为这个测试需要some!但是如果我只写这个断言,而测试运行良好(这个断言失败),Typescript 会对下一行不满意,因为它不会仅仅因为断言而将result视为some。 -
你可以使用
elem:expect(elem('abcd', result)).toEqual(true)。
标签: typescript testing jestjs fp-ts