gpt4 book ai didi

javascript - 安装时如何从 enzyme 实例中获取 HOC 包装的组件功能?

转载 作者:行者123 更新时间:2023-11-29 18:46:16 25 4
gpt4 key购买 nike

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

child 也在使用 material-ui withStyles,所以它围绕组件创建了一个 HOC。

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

目前我的解决方案是这样的:

  • 安装父级,找到子级
  • 调用 child.instance().fetchFunction().then(() => expect(..))

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

child.instance(...).fetchFunction is not a function

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

我可以测试单独的 fetch 调用,然后使用 shallow 测试组件并将 Prop 传递给它,就好像状态已更改一样,但这并不能证明它们可以一起工作。

这是我重现问题的代码和框:

Edit Testing Async componentDidMount

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

App.js

import React from "react";
import Child from "./Child";

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

export default App;

Child.js

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

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"
);
});
});
});
});

最佳答案

写完后,我找到了答案,但我觉得这值得分享,因为我对此很困惑。

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

enzyme docs for find(selector)

关于javascript - 安装时如何从 enzyme 实例中获取 HOC 包装的组件功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53770411/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com