我正在尝试测试一个组件,该组件在其内部状态从 false 变为 true 时呈现两个不同的子组件:当它为 false 时,它呈现一个按钮,如果按下该按钮,则将状态从 false 更改为 true 并呈现另一个。另一种是在提交时执行相反操作的表单。
我试图监视 useState 钩子以测试它是否被实际调用。但是通过模拟module,当我在测试的第二部分需要它来测试之后呈现的表单时,实际的 setState 将不起作用。
这是我的组件:
import React, { useState } from 'react';
const MyComponent = ({handleChange, handleInput}) => {
const [state, setState] = useState(false);
return (
<div>
{!state
? (
<button
data-test="button1"
type="button"
onClick={() => setState(true)}
>
RenderForm
</button>
)
: (
<form onSubmit={() => setState(false)}>
<input type="text" onChange={e => handleChange(e)} />
<button type="submit">
Submit Form
</button>
<button type="button" onClick={() => setState(false)}>
Go Back
</button>
</form>
)
}
</div>
);
};
export default MyComponent;
这是我的测试:
import React from 'react';
import { mount } from 'enzyme';
import MyComponent from './MyComponent';
describe('MyComponent', () => {
let component;
const mockChange = jest.fn();
const mockSubmit = jest.fn();
const setState = jest.fn();
const useStateSpy = jest.spyOn(React, 'useState');
useStateSpy.mockImplementation(init => [init, setState]);
beforeEach(() => {
component = mount(<MyComponent handleChange={mockChange} handleSubmit={mockSubmit}/>);
});
afterEach(() => {
component.unmount();
});
it('calls setState when pressing btn', ()=> {
component
.find('[data-test="button1"]')
.simulate('click')
expect(setState).toHaveBeenCalledWith(true) // passes
})
it('calls handleChange when input changes value', () => {
component
.find('[data-test="button1"]') //can't be found
.simulate('click')
component
.find('input')
.simulate('change', { target: { value: 'blabla' }})
expect(mockChange).toHaveBeenCalled() // doesn't pass
})
});
我知道是什么问题,但我不知道如何解决它。有没有办法模拟 setState?或者有没有办法拆分测试,这样它们就不会相互干扰?