使用 Jest 和酶测试 React Typescript 组件中的副作用
Testing side effects in React Typescript components with Jest and enzyme
我真的很想了解如何使用 React + TS 进行正确的单元测试,但到目前为止真的很艰难。我有两个非常简单的组件用于隔离事物。我将在底部包含组件,这样我就不会把东西弄得太乱。
很简单,点击Button
,状态变量data
中的'hello'变为'world'显示在InnerComponent
中。 From everything I've seen,该模式是测试文档中的副作用,而不是尝试测试状态变化本身(谢天谢地,我有一次噩梦试图使用 Typescript 访问包装器实例中的状态).但是,eslint
讨厌screen
,TS找不到findByText
。相反,我在下面的测试中注意到的行中收到错误 Property 'findByText' does not exist on type 'Screen'.ts(2339)
:
/* OuterComponent.test.tsx */
import { findByText } from '@testing-library/react';
import { mount } from 'enzyme';
import React from 'react';
import OuterComponent from './OuterComponent';
describe('OuterComponent', () => {
it('does something on click', async () => {
const wrapper = mount(<OuterComponent />);
/* eslint-disable-next-line no-restricted-globals */
expect(await screen.findByText('hello')).not.toBe(null); // error here
wrapper.find('Button').simulate('click');
/* eslint-disable-next-line no-restricted-globals */
expect(await screen.findByText('world')).not.toBe(null); // error here
});
});
这感觉像是一个非常标准的场景,那么你们这些使用 TS 的人如何测试这种类型的东西?这里是 OuterComponent
:
/* OuterComponent.tsx */
import React, { useState } from 'react';
import { Button } from 'react-bootstrap';
import InnerComponent from './InnerComponent';
const initialData = 'hello';
const OuterComponent: React.FC = () => {
const [data, setData] = useState<string>(initialData);
const clickHandler = () => {
if (data === 'hello') {
setData('world');
} else {
setData('hello');
}
};
return (
<div className="Outer">
<Button onClick={clickHandler}>Click</Button>
<InnerComponent data={data} />
</div>
);
};
export default OuterComponent;
这里是 InnerComponent
:
/* InnerComponent.tsx */
import React from 'react';
import { Card } from 'react-bootstrap';
interface TheseProps {
data: string;
}
const InnerComponent: React.FC<TheseProps> = ({ data }) => {
return (
<div className="Inner">
<Card>
<Card.Text>{data}</Card.Text>
</Card>
</div>
);
};
export default InnerComponent;
从“@testing-library/react”导出了一个单独的“屏幕”对象。具有 findByText 方法。不幸的是,您必须手动从库中抓取屏幕,因为当您没有明确导入时,自动导入只是认为它是全局“屏幕”。
我真的很想了解如何使用 React + TS 进行正确的单元测试,但到目前为止真的很艰难。我有两个非常简单的组件用于隔离事物。我将在底部包含组件,这样我就不会把东西弄得太乱。
很简单,点击Button
,状态变量data
中的'hello'变为'world'显示在InnerComponent
中。 From everything I've seen,该模式是测试文档中的副作用,而不是尝试测试状态变化本身(谢天谢地,我有一次噩梦试图使用 Typescript 访问包装器实例中的状态).但是,eslint
讨厌screen
,TS找不到findByText
。相反,我在下面的测试中注意到的行中收到错误 Property 'findByText' does not exist on type 'Screen'.ts(2339)
:
/* OuterComponent.test.tsx */
import { findByText } from '@testing-library/react';
import { mount } from 'enzyme';
import React from 'react';
import OuterComponent from './OuterComponent';
describe('OuterComponent', () => {
it('does something on click', async () => {
const wrapper = mount(<OuterComponent />);
/* eslint-disable-next-line no-restricted-globals */
expect(await screen.findByText('hello')).not.toBe(null); // error here
wrapper.find('Button').simulate('click');
/* eslint-disable-next-line no-restricted-globals */
expect(await screen.findByText('world')).not.toBe(null); // error here
});
});
这感觉像是一个非常标准的场景,那么你们这些使用 TS 的人如何测试这种类型的东西?这里是 OuterComponent
:
/* OuterComponent.tsx */
import React, { useState } from 'react';
import { Button } from 'react-bootstrap';
import InnerComponent from './InnerComponent';
const initialData = 'hello';
const OuterComponent: React.FC = () => {
const [data, setData] = useState<string>(initialData);
const clickHandler = () => {
if (data === 'hello') {
setData('world');
} else {
setData('hello');
}
};
return (
<div className="Outer">
<Button onClick={clickHandler}>Click</Button>
<InnerComponent data={data} />
</div>
);
};
export default OuterComponent;
这里是 InnerComponent
:
/* InnerComponent.tsx */
import React from 'react';
import { Card } from 'react-bootstrap';
interface TheseProps {
data: string;
}
const InnerComponent: React.FC<TheseProps> = ({ data }) => {
return (
<div className="Inner">
<Card>
<Card.Text>{data}</Card.Text>
</Card>
</div>
);
};
export default InnerComponent;
从“@testing-library/react”导出了一个单独的“屏幕”对象。具有 findByText 方法。不幸的是,您必须手动从库中抓取屏幕,因为当您没有明确导入时,自动导入只是认为它是全局“屏幕”。