我正在使用fp-ts
,我用 Jest 编写单元测试。在许多情况下,我正在测试可以为空的结果,通常用Option
or表示Either
(通常是 array find
s)。如果结果为无(以Option
示例为例),那么使测试失败的最符合人体工程学的方法是什么,并继续知道这个结果是一些?
这是我目前如何解决问题的示例:
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
's 类型。在许多情况下,必须编写它很繁重,需要编写和导出接口仅用于测试目的(这也不符合人体工程学)。
有没有办法简化这种测试?
编辑:这是一个更接近真实条件的测试用例:
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',
});
});
});