首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在挂载时从enzyme实例中获取即席封装的组件函数?

如何在挂载时从enzyme实例中获取即席封装的组件函数?
EN

Stack Overflow用户
提问于 2018-12-14 05:34:25
回答 1查看 2.7K关注 0票数 2

我有父fetch子组件,子组件在componentDidMount中运行->。fetch在父组件之上的redux存储中设置状态,这会导致子组件以不同的方式显示。

子组件也在使用material-ui withStyles,因此它在组件周围创建了一个HOC。

在我的测试中,我需要挂载父组件,找到子组件,然后查看fetch是否正确地更改了状态并导致子组件更新。

到目前为止我的解决方案是:

调用child.instance().fetchFunction().then(() => expect(..))查找

  • 装载父进程,查找
  • 子进程

但是,在child上调用instance()会返回HOC,因此我得到了错误:

child.instance(...).fetchFunction不是函数

我见过的所有解决方案都使用shallowdive来绕过HOC,但是如果我使用shallow,我将不得不在测试中创建一个模拟存储,并且它实际上不会将其作为集成测试进行测试。

我可以测试单独的fetch调用,然后使用shallow测试组件,并将属性传递给它,就像状态发生了变化一样,但这并不能证明它们都在一起工作。

这是一个代码沙盒,我在其中复制了这个问题:

下面是一些示例代码(基本上是codesandbox):

App.js

代码语言:javascript
运行
复制
import React from "react";
import Child from "./Child";

class App extends React.Component {
  render() {
    return <Child />;
  }
}

export default App;

Child.js

代码语言:javascript
运行
复制
import React from "react";
import { withStyles } from "@material-ui/core/styles";

const childStyles = {
  margin: 0
};

class Child extends React.Component {
  state = {
    groceries: [],
    errorStatus: ""
  };

  componentDidMount() {
    console.log("calling fetch");

    this.fetchCall();
  }

  fetchCall = () => {
    return fetch("/api/v1/groceries")
      .then(this.checkStatus)
      .then(this.parseJSON)
      .then(this.setStateFromData)
      .catch(this.setError);
  };

  checkStatus = results => {
    if (results.status >= 400) {
      console.log("bad status");

      throw new Error("Bad Status");
    }

    return results;
  };

  setError = () => {
    console.log("error thrown");

    return this.setState({ errorStatus: "Error fetching groceries" });
  };

  parseJSON = results => {
    console.log("parse json");

    return results.json();
  };

  setStateFromData = data => {
    console.log("setting state");

    return this.setState({ groceries: data.groceries });
  };

  render() {
    const { groceries } = this.state;

    return (
      <div id="app">
        {groceries.map(grocery => {
          return <div key={grocery.id}>{grocery.item}</div>;
        })}
      </div>
    );
  }
}

export default withStyles(childStyles)(Child);

App.test.js

代码语言:javascript
运行
复制
import Enzyme from "enzyme";
import Adapter from "enzyme-adapter-react-16";
import React from "react";
import { mount } from "enzyme";
import App from "./App";
import Child from "./Child";

Enzyme.configure({ adapter: new Adapter() });

const mockResponse = (status, statusText, response) => {
  return new window.Response(response, {
    status: status,
    statusText: statusText,
    headers: {
      "Content-type": "application/json"
    }
  });
};

describe("App", () => {
  describe("ChildApp componentDidMount", () => {
    it("sets the state componentDidMount", () => {
      console.log("starting test for 200");

      global.fetch = jest.fn().mockImplementation(() =>
        Promise.resolve(
          mockResponse(
            200,
            null,
            JSON.stringify({
              groceries: [{ item: "nuts", id: 10 }, { item: "greens", id: 3 }]
            })
          )
        )
      );

      const renderedComponent = mount(<App />);
      const childApp = renderedComponent.find(Child);

      childApp
        .instance()
        .fetchCall()
        .then(() => {
          console.log("finished test for 200");
          expect(childApp.state("groceries").length).toEqual(2);
        });
    });

    it("sets the state componentDidMount on error", () => {
      console.log("starting test for 500");

      window.fetch = jest
        .fn()
        .mockImplementation(() =>
          Promise.resolve(
            mockResponse(
              400,
              "Test Error",
              JSON.stringify({ status: 400, statusText: "Test Error!" })
            )
          )
        );

      const renderedComponent = mount(<App />);
      const childApp = renderedComponent.find(Child);
      childApp
        .instance()
        .fetchCall()
        .then(() => {
          console.log("finished test for 500");
          expect(childApp.state("errorStatus")).toEqual(
            "Error fetching groceries"
          );
        });
    });
  });
});
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-12-14 05:34:25

写完这篇文章后,我找到了答案,但我觉得这是值得分享的,因为我对它感到非常困惑。

不使用app.find(Child) (组件构造函数),而使用app.find('Child') (组件显示名称)。这将找到实际的组件,而不是hoc包装的组件。

enzyme docs for find(selector)

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53770411

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档