如何模拟一个函数并期望它被调用?

Iza*_*ise 8 node.js reactjs jestjs react-testing-library

我是反应测试库的新手,很长一段时间以来我一直在尝试测试一个功能。例如,我想检查当单击按钮时是否调用给定函数并且它抛出错误。因此,我们将非常感谢任何帮助,如果可能的话,请与我分享任何有用的资源。

登录.js

export default class SignIn extends Component {
    constructor(props) {
        super(props);
        this.state = {
        };
    }

    handleClose = (event, reason) => { };
    validate = () => { };
    change = (e) => { };
    onSubmit = (e) => { };

    render() {
        return (<div>...</div>);
    }
}
Run Code Online (Sandbox Code Playgroud)

完整: https: //github.com/blaise82/react-testing-library-try/blob/master/src/views/SignIn.js

这是我的测试

it('should submit form', async () => {
    const { getByLabelText, getByText, container, debug } = render(<SignIn />);
    const change = jest.fn();
    const onSubmit = jest.fn();
    const email = getByLabelText('email');
    const password = getByLabelText('password');
    const submit = getByLabelText('submit');

    userEvent.type(email, 'octopusbn@gmail.com');
    expect(email.value).toBe('octopusbn@gmail.com');
    expect(password.value).toBe('');
    expect(change).toHaveBeenCalled();

    console.log(password)
    await userEvent.click(submit);
    expect(onSubmit).toHaveBeenCalled();

});
Run Code Online (Sandbox Code Playgroud)

完整: https: //github.com/blaise82/react-testing-library-try/blob/master/src/test/signin.test.js

结果

>    Expected number of calls: >= 1
>     Received number of calls:    0
Run Code Online (Sandbox Code Playgroud)

请让知道我做错了什么。

GitHub 上的完整代码:https ://github.com/blaise82/react-testing-library-try

dha*_*zen 13

您可以通过模拟来自组件外部的所有内容(也称为依赖项)来测试函数,例如 prop 回调、外部库 api 等。

在开始之前,我们先了解一下组件中的所有功能。浏览该组件,我可以将它们列出如下:

  1. 元素上的事件处理程序[例如组件中的handleClose, onSubmit, ]change
  2. 组件内部的函数,不与组件外部的状态/函数交互 [ validate]
  3. 被调用的 prop 函数/库 api [ axios.post]

让我们一一讨论——

  • 事件处理程序 &
  • 组件内部的函数不与组件外部的状态/函数交互

==> 可以安全地调用附加到元素的事件处理程序。如果它们被调用,您不需要测试它们。相反,您应该测试的是调用它们的后效。还有像这样的功能validate

change让我们以您要测试的函数为例。调用此函数后会设置状态,并且状态会反映到表单元素中。我们可以使用这样的助手来断言表单元素的值。

  • 被调用的 prop 函数/库 api [ axios.post]

==> 可以模拟和测试这些函数的调用/参数数量。 https://jestjs.io/docs/en/mock-functions.html#mocking-modules

除了上面链接中给出的嘲笑笑话片段之外,在您的情况下 -

axios.post.toHaveBeenCalledWith(expectedParms);

您还可以让它返回您想要的结果/错误并测试相应的组件行为。

希望您觉得这有帮助。干杯!


小智 2

我认为这是因为您实际上并未将模拟函数传递给组件。您只是实例化两个常量,它们恰好具有您要监视的函数的名称,但实际上并未在组件中的任何地方使用。

听起来您想监视组件的内部函数以查看它们是否已被调用。

这是基于帖子(下面链接)的示例(未经测试),可能会对您有所帮助。

describe('spying on "onSubmit" method', () => {
  it('should call onSubmit when the button is clicked', () => {
    const wrapper = shallow(<SignIn />); 
    const instance = wrapper.instance();

    jest.spyOn(instance, 'onSubmit');

    wrapper.find('button').simulate('click');
    expect(instance.onSubmit).toHaveBeenCalled();
  });
});
Run Code Online (Sandbox Code Playgroud)

帖子:https://bambielli.com/til/2018-03-04-directly-test-react-component-methods/#spying-on-incrementcounter