Я использую fp-ts
, и я пишу юнит-тесты с Jest. Во многих случаях я тестирую обнуляемые результаты, часто представленные Option
или Either
(обычно массив find
s). Какой самый эргономичный c способ заставить тест провалиться, если результата нет (взяв 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 с ранним возвратом не очень эргономична c.
Я мог бы альтернативно написать as
утверждение:
// ...
it(`should do something with a "some" result`, () => {
const result = someFunc('abcd') as Option.Some<string>;
expect(result.value).toEqual('abcd');
});
// ...
Но недостатком здесь является то, что я должен переписать тип some
. Во многих случаях необходимость писать это тяжело, требует написания и экспорта интерфейса с единственной целью тестирования (что также не является эргономикой c).
Есть ли способ упростить этот вид тестирования ?
Редактировать: Вот тестовый пример, который ближе к реальным условиям:
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',
});
});
});