【问题标题】:State no updating in class component when testing method with jest用玩笑测试方法时声明类组件中没有更新
【发布时间】:2021-10-06 09:56:03
【问题描述】:

我正在尝试在上下文提供程序中测试我的方法。我在方法中有一个分支要覆盖,这就是我要扼杀的。只有特定条件发生时才进入特定分支:if (offset !== 0 && total !== 0 && offset >= total)

在下面查看我的类组件:

class JourneyProvider extends Component<
  {
    children: ReactNode;
  },
  JourneyContextData
> {
  constructor(props: { children: ReactNode }) {
    super(props);
    this.state = {
      ...defaultValues,
    };
  }

  getContextValue = (): JourneyContextData => {
    const { products, total, limit, offset, loading, disabled, setProducts } =
      this.state;
    return {
      products,
      total,
      limit,
      offset,
      loading,
      disabled,
      setProducts,
    };
  };

  setProducts = async (): Promise<void> => {
    const { limit, offset, total, products } = this.state;
    if (total === 0 || offset < total) {
      const gqlRequest = new GQLRequest(query);
      this.setLoading(true);
      try {
        await gqlRequest.post().then(({ products: { edges, totalCount } }) => {
          const newOffset = offset + limit;
          this.setState({
            products,
            total: totalCount,
            offset: newOffset,
          });
          this.setLoading(false);
          // Disable button if there are no more products
          if (offset !== 0 && total !== 0 && offset >= total) {
            // never gets in here when testing.
            this.setDisabled(true);
          }
        });
      } catch (e) {
        this.setLoading(false);
      }
    }
  };
}

这是我的测试:

  it("setProducts is successful and disable button", async () => {
    const wrapper = shallow(
      <JourneyProvider>
        <div>test</div>
      </JourneyProvider>
    ) as any;

    const result = {
      products: {
        edges: [
          {
            node: {
              id: "1",
              name: "test-name",
            },
          },
        ],
        totalCount: 1,
      },
    };

    mockedClient.post.mockResolvedValueOnce(result);

    jest
      .spyOn(ProductsQuery, "getProductsQuery")
      .mockResolvedValueOnce(new Query("test", true) as never);

    const setLoadingSpy = jest.spyOn(wrapper.instance(), "setLoading");
    const setDisabledSpy = jest.spyOn(wrapper.instance(), "setDisabled");

    wrapper.state().limit = result.products.totalCount;
    console.log(wrapper.state().offset); //this returns 0
    await wrapper.instance().setProducts();
    console.log(wrapper.state().offset); //this returns 0
    expect(setLoadingSpy).toHaveBeenCalledWith(true); // this passes

    expect(setLoadingSpy).toHaveBeenCalledWith(false); // this passes

    expect(setDisabledSpy).toHaveBeenCalledWith(true); // this fails
  });

【问题讨论】:

标签: reactjs jestjs state enzyme


【解决方案1】:

您应该更改进行比较的代码中的逻辑,因为您使用的是陈旧状态,请记住,对 setState 的调用不会立即更改状态。比较您为状态设置的新值而不是旧状态值

          if (newOffset !== 0 && totalCount !== 0 && newOffset >= totalCount) {

或将该代码放在 setState 回调中,以确保您使用的是更新后的值

...
          const newOffset = offset + limit;
          this.setState({
            products,
            total: totalCount,
            offset: newOffset,
          }, () => {
            this.setLoading(false);
            if (offset !== 0 && total !== 0 && offset >= total) {
              this.setDisabled(true);
            }
          });
...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-14
    • 2020-12-15
    • 2019-12-19
    • 2020-09-03
    • 2017-11-28
    • 1970-01-01
    • 2021-12-31
    • 2023-03-11
    相关资源
    最近更新 更多