如何测试是否在酶和玩笑中设置状态

问题描述 投票:0回答:1

我是刚开始使用Jest和Enzyme。我有一个组件,它设置一些从父组件传递下来的道具。根据所调用的API调用,我想确保相应地设置这些道具。在此代码中,我想测试是否正确调用了setUseruser。这是我的代码:

LoginButton.js

import React, { useState } from 'react';
import { useHistory } from 'react-router-dom';
import './LoginButton.css';

const LoginButton = (props) => {

  const history = useHistory();

  const [user, setUser] = useState({});

  const login = async (e) => {
    e.preventDefault();
    const loginRequest = {
      userName: props.username,
      password: props.password
    };
    try {
      const loginResponse = await fetch('/login', {
        method: 'POST',
        body: JSON.stringify(loginRequest),
        headers: {
          'Content-Type': 'application/json',
        }
      });
      const user = await loginResponse.json();
      console.log("User: ", user);
      if (user.status && user.message) {
        props.setSubmitError(user.message);
      } else if (user.userStatus && user.userStatus === "Locked" || user.userStatus === "Deactivated") {
        props.setSubmitError(user.message);
      } else {
        setUser(user);
        // TODO: do something with user, pass it to dashboard component
        history.push('/dashboard');
      }
    } catch (err) {
      props.setSubmitError(user.message);
    }
  }

  return (
    <button styleName="sign-in-btn" onClick={login}>
      Sign me in!
    </button>
  )
}

export default LoginButton; 

这是我在LoginButton.test.js中这样做的尝试:

// mock useHistory or else it will fail in every test
jest.mock('react-router-dom', () => ({
  useHistory: () => ({
    push: jest.fn()
  })
}));

describe('LoginButton', () => {
  const setUser = jest.fn();
  const useStateSpy = jest.spyOn(React, 'useState');
  useStateSpy.mockImplementation((init) => [init, setUser]);

  it('sets user state properly', () => {

    let props = {
      setSubmitError: jest.fn()
    }

    const fakeResponse = {userName: "user123",  success: true};
    const mockJsonPromise = Promise.resolve(fakeResponse);
    const mockFetchPromise = Promise.resolve({
      json: () => {
        mockJsonPromise
      }
    });

    global.fetch = jest.fn().mockImplementation(mockFetchPromise);
    const wrapper = shallow(<LoginButton
      {...props} 
    />);
    const signInButton = wrapper.find('button')
    signInButton.simulate('click', {
      preventDefault: () => {},
    });
    expect(global.fetch).toHaveBeenCalledTimes(1);
    // here i expect setUser to have been called already.. but I get an error saying number of calls: 0
    expect(setUser).toHaveBeenCalledWith(fakeResponse);

    global.fetch.mockClear();
    delete global.fetch;

  });
})

不幸的是,我收到一条错误消息,说从未调用过setUser,我不确定为什么。我觉得我已经正确设置了测试,并且根据传入的fakeResponse,我相信它应该进入m else语句并正确设置用户。任何帮助,将不胜感激。谢谢

reactjs jestjs enzyme
1个回答
0
投票

简短的答案是:不要。

您不需要测试setUser。这是实现细节,并且在组件内部。如果看起来有用,您可以测试setSubmitError回调或history.push被调用(您可能还需要onSuccess处理函数来传递返回的用户,因此您也可以对其进行测试)。但是测试像状态设置程序这样的纯内部实现违反了black box testing的原理。

如果您真的想在测试login函数时获得特定说明,请考虑将其提取为辅助函数,可以在组件上下文之外进行测试。这样就更清楚了给定输入的预期输出是什么。

© www.soinside.com 2019 - 2024. All rights reserved.