我在编写测试时遇到的一个烦人的问题如下所示:
function getData(): { isLoading: true } | { isLoading: false; data: string } {
return {
isLoading: false,
data: "hello world",
};
}
describe(getData, () => {
it("behaves correctly", () => {
const result = getData();
expect(result.isLoading).toBe(false);
// Despite already have asserted that isLoading is false,
// Typescript isn't aware of it and
// I still need to narrow the type by throwing an error
if (result.isLoading) {
throw new Error("expected isLoading to be false");
}
expect(result.data).toBe("hello world");
});
});
有没有一种简洁的方法来避免这种不必要的错误抛出?
jest API 的实现方式并未充分利用 TypeScript 的功能。
您可以以对 TypeScript 更友好的方式编写测试,如下所示:
describe(getData, () => {
it("behaves correctly", () => {
const result = getData();
if (result.isLoading) {
expect(true).toBe(false);
} else {
expect(result.data).toBe("hello world");
}
});
});
或者像这样:
type Loading = { isLoading: true };
type NotLoading = { isLoading: false; data: string };
type Result = Loading | NotLoading;
function getData(): Result {
return {
isLoading: false,
data: "hello world",
};
}
function isNotLoading(result: Result): result is NotLoading {
if (result.isLoading) {
expect(true).toBe(false);
return false;
} else {
return true;
}
}
describe(getData, () => {
it("behaves correctly", () => {
const result = getData();
if (isNotLoading(result)) {
expect(result.data).toBe("hello world");
}
});
});