首页 > 解决方案 > 输入未在反应测试库上更新,因此测试失败,但它确实在实际应用程序上更新

问题描述

我想测试当我在输入(inputA)中输入一个值时,另一个输入(inputB)会更新一个值。

inputA 接受邮政编码,例如:“10999”,在 inputB 显示位置之后:“Berlin”

这适用于实际应用程序,我输入 inputA,然后 inputB 得到更新。

当在 inputA 上输入 ome 类型时,会调度一个操作,然后 inputB 从 redux 状态中获取一个新值。

这是我的测试代码,有什么想法为什么它不会在测试中使用“Ort”占位符更新输入,但在实际应用程序中会更新?

import { render, withIntl, withStore, configureStore, withState } from "test-utils-react-testing-library";
import { screen, fireEvent, withHistory, withRoute, within } from "@testing-library/react";
import configureMockStore from 'redux-mock-store';

import ProfileForm from "./ProfileForm";
import PersonalDetails from "../PersonalDetails/PersonalDetails";

const STATE = {
  locations: { locations: {} },
  streets: { streets: {} },
  password: {}
};

const mockStore = configureMockStore();
const STORE = mockStore({
  streets: {
    isFetching: false,
  },
  locations: {
    locations: {
      isFetching: false,
    },
  },
  user: {
    session: {
      impersonated_access_token: "",
    },
    updateError: "error",
  },
});

const props = {
  id: "user1",
  user: { email: "max@muster.de" },
  locations: {},
  onSubmit: jest.fn(),
};
  
beforeEach(jest.resetAllMocks);

describe("ProfileForm", () => {
    describe("on personal details change", () => {
      it("auto selects only location when postalcode becomes selected", () => {
        const locations = { electricity: { [PLZ_1]: [LOCATION_OBJ_1] } };
        const user = { postalcode: null };

        render(<ProfileForm {...props} user={user} locations={locations} />, [...decorators, withStore(STORE)]);
        
        const input = screen.getByPlaceholderText("PLZ");
        fireEvent.change(input, { target: { value: "10999" } })
        
        screen.debug(screen.getByPlaceholderText("PLZ"))
        screen.debug(screen.getByPlaceholderText("Ort"))

        expect(screen.getByPlaceholderText("Ort")).toHaveValue("Berlin");
      });

});

标签: reduxreact-testing-library

解决方案


我遇到了类似的问题,发现微任务队列中的更改并不总是刷新,因此在测试完成运行之前不会应用/呈现更改。对我jest.useFakeTimers()有用的是在测试用例开始时调用,然后await act(async () => { jest.runOnlyPendingTimers() });在调用fireEvent.<some-event>(...)

在你的情况下:

it("auto selects only location when postalcode becomes selected", async () => {
  jest.useFakeTimers();
  const locations = { electricity: { [PLZ_1]: [LOCATION_OBJ_1] } };
  const user = { postalcode: null };

  render(<ProfileForm {...props} user={user} locations={locations} />, [...decorators, withStore(STORE)]);
        
  const input = screen.getByPlaceholderText("PLZ");
  fireEvent.change(input, { target: { value: "10999" } })
  await act(async () => {
    jest.runOnlyPendingTimers();
  });      
  screen.debug(screen.getByPlaceholderText("PLZ"))
  screen.debug(screen.getByPlaceholderText("Ort"))
  expect(screen.getByPlaceholderText("Ort")).toHaveValue("Berlin");

});

推荐阅读