首页 > 解决方案 > 如何使用 jest 设置反应功能组件的状态

问题描述

我有一个组件,它有一个表单和模态。单击提交时,会弹出模式并在确认后发送对后端的调用。

最初,通过使用状态 (displayModal) 隐藏模式。

我正在尝试通过在显示模式中找到按钮来测试 API 调用。但找不到它,因为它不在 DOM 上(显示模式为假)。

如何在开玩笑测试中设置状态。

const MyTypeComponent: FunctionComponent<MyType> = ({
props1,
props2,
ownProp1,
ownProp2
}) => {
  //There are two use effects to do something
  //set the modal state
  const [displayModal, setdisplayModalOpen] = useState(false);
  const updateStatusquantityService = () => {
    //Call an API
  };
  const InventoryStatusquantityFormSubmitted = (form) => {
    if (!form.isValid) {
      return;
    }
    //If form valid, display the modal;
  
  };
  return (
    <>
          <Modal
            isOpen={displayModal}
            setIsOpen={setdisplayModalOpen}
            id={"InventoryStatusTypeModal"}
          >
           //Usual Modal stuff and then button
            <Button id={"statusquantityUpdateBtn"} variant="primary" label="Update" onClick={() => updateStatusquantityService()}/>
          </Modal>
          <Form>
             //On form submit, call InventoryStatusquantityFormSubmitted() and display the modal
          </Form>
    </>
  );
};
export default connect(
  (state: RootState) => ({
   //map states to props
  }),
  (dispatch: ThunkDispatch) => ({
    //map props 1 and props 2
  })
)(InventoryStatusquantity);

当我试图statusquantityUpdateBtn通过如下方式找到模式按钮“”来触发点击时,我得到一个空值,因为模式由于它的值而不可见。

it('Should submit status types form11', () => {
    const submitButtonOnModal = wrapper.find('#statusquantityUpdateBtn').
});

我正在尝试通过使用更新状态

wrapper.instance().setdisplayModalOpen(true)

但是得到错误 wrapper.instance().setdisplayModalOpen不是一个函数。

我正在使用简单的安装命令进行安装:

export const mountWithMemoryRouter = (element: JSX.Element) => {
    return mount(<MemoryRouter>{element}</MemoryRouter>);
};
 
wrapper = mountWithMemoryRouter(
    <Theme>
        <Provider store={store}>
            <MyTypeComponent
                {...defaultProps}
                ownProp1={null}
                ownProp2={null}
            />
        </Provider>
    </Theme>
);
 

标签: javascriptreactjsreduxjestjsuse-state

解决方案


这些状态钩子的作用域是函数,所以函数之外的任何东西都不能访问它们。这就是为什么您会收到“不是函数”错误的原因。它类似于

function x() {
   const y = 0
}

x().y // Error

我在您的代码中没有看到任何setdisplayModalOpen(true)为了显示模态而调用的内容。

假设您只提供了部分代码(但它是在您的计算机上编写的),并且有一些按钮或正在运行的东西setdisplaymodalOpen(true),(我假设有一个表单提交按钮)那么如果我需要对此进行测试,我会改为使用React 测试库并有类似的东西

import { render, screen, fireEvent, waitFor } from 'react-testing-library'
import MyComponent from './components/one-to-test'

test('does whatever', async () => {
  render(<MyComponent/>)
  const showModalBtn = screen.getByText('Text of Button You Click to Display Modal')
  fireEvent.click(showModalBtn)
  await waitFor(() => expect(screen.getByText('Update')).not.toBeNull())
  // You are now assured the modal is visible and can continue with the rest of your test
})

在这个测试中,您首先指示 React 测试库渲染可以显示/隐藏模式的组件(即表单)。(假设您单击一个按钮以显示模态),您获得该按钮,然后模拟单击该按钮,然后您的测试等待模态可见(在这种情况下,它会等到“更新" 模式中包含的按钮可见)。

然后你可以继续测试你的模态(比如用另一个fireEvent.click(updateBtn).

如果您想模拟您的 API,那么您还可以添加

jest.mock('./my/api/library', () => ({
  whateverApiCall: jest.fn(() => whateverItShouldReturn)
})

现在,当您单击表单提交按钮时,它将调用您的模拟 API 函数,该函数返回您定义它返回的任何内容,并假设它没有抛出/拒绝,您的模态将显示,然后您如上所述继续。


推荐阅读