在使用 Jest 进行 TypeScript 项目的单元测试时,有时会遇到以下错误:
Type 'string' is not assignable to type 'Matcher'.
出现这个错误的原因是 Jest 的类型定义文件定义了它所支持的 Matcher(匹配器),而 TypeScript 无法正确地推断出我们所使用的 Matcher 类型。
要解决这个问题,我们需要告诉 TypeScript 正确的 Matcher 类型。具体而言,我们可以通过手动指定所使用的 Matcher 来解决这个问题。
以下是我们如何手动指定 Matcher 类型的例子:
import { render } from "@testing-library/react";
test("renders login text", () => {
const { getByText } = render(<Login />);
const linkElement = getByText(/login/i);
expect(linkElement).toMatchObject({ textContent: "Login" } as const);
});在这个例子中,我们明确将 Matcher 的类型指定为 const。这告诉 TypeScript 在这个例子中 Matcher 的类型是固定的,并且可以和实际这个对象匹配。
如果你的项目中有很多这样的错误,你可能想要为它们创建一个类型定义文件。
以下是我们如何创建这样一个文件的例子:
// www.javascriptcn.com code example
import '@testing-library/jest-dom';
import { Matcher } from '@testing-library/jest-dom/types/matchers';
declare global {
namespace jest {
interface Matchers<R> {
toHaveTextContent(
expected: string | RegExp,
options?: { normalizeWhitespace?: boolean },
): R;
}
}
}
expect.extend({
toHaveTextContent(
element: HTMLElement,
expected: string | RegExp,
options?: { normalizeWhitespace?: boolean },
) {
const normalize = normalizeWhitespace(options);
const actual = normalize(element.textContent || '');
const pass = RegExp(`^${expected.source}$`).test(actual);
if (pass) {
return {
message: () => `expected "${element.textContent}" to not match expression ${expected}`,
pass: true,
};
} else {
return {
message: () => `expected "${element.textContent}" to match expression ${expected}`,
pass: false,
};
}
},
});
function normalizeWhitespace(options?: { normalizeWhitespace?: boolean }) {
return (text: string) => {
let normalized: string = text;
if (options?.normalizeWhitespace) {
normalized = text.replace(/\s+/g, ' ').trim();
}
return normalized;
};
}在这个例子中,我们首先导入了测试库的类型定义文件,然后将它们扩展到全局命名空间中。这允许我们扩展测试库的 Matcher 类型,并将其用于我们的测试。
然后,我们定义了一个 toHaveTextContent Matcher,并在其上使用 expect.extend 来扩展 Jest。在扩展中,我们使用传递给 Matcher 的参数来执行实际的匹配算法。
最后,我们定义了一个额外的覆盖类型来支持选项的 normalizeWhitespace 标志,允许用户指定是否应将文本规范化为单个空格。
总的来说,手动指定 Matcher 的类型或编写自定义 Matcher 是解决这个错误的两种方法。无论你选择哪种方法,你都应该确保你的测试不再出现这个错误,并且可以正确地执行。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d606c8a941bf7134b9de7c