单元测试:用酶 return 反应上下文 api 一个空对象
Unit testing: react context api with enzyme return an empty object
我第一次尝试使用 React 上下文 API 将信息从主组件传递到孙组件。
首先我创建了一个上下文
const MyContext = React.createContext({});
export default MyContext;
这里是设置上下文值的主要组件
import MyContext from "./MyContext.js";
import ParentComponent from "./ParentComponent.js";
function App() {
return (
<div>
<MyContext.Provider value={{ foo: 12 }}>
<ParentComponent />
</MyContext.Provider>
</div>
);
}
父组件不关心上下文,只是为了创建孙组件
import ChildComponent from "./ChildComponent.js";
class ParentComponent extends Component {
render() {
return (
<div>
Parent
<ChildComponent />
</div>
);
}
}
export default ParentComponent;
这里是读取上下文的子组件
import MyContext from "./MyContext.js";
class ChildComponent extends PureComponent {
constructor() {
super();
this.state = {
bar: 456
};
}
render() {
return (
<div>
<MyContext.Consumer>
{({ foo }) => (
<div>
<h1>Hello I'm the ChildComponent</h1>
<h2>Context value: {foo}</h2>
<h2>State value: {this.state.bar}</h2>
<button onClick={() => this.setState({ bar: foo })}>
Click me
</button>
</div>
)}
</MyContext.Consumer>
</div>
);
}
}
export default ChildComponent;
到目前为止没问题。一切都按预期工作。 ChildComponent 已检索上下文值。
当我尝试用 jest/enzyme 测试它时,问题就来了。我无法设置上下文
it("Should test the context value", () => {
let wrapper = mount(<ChildComponent />, {
context: { foo: 987 }
});
expect(wrapper.state("bar")).toEqual(456);
expect(wrapper.context("foo")).toEqual(987);
});
最后一次期望失败,上下文值为空对象。所以 foo 是未定义的
我在这里重现了这个问题:
https://codesandbox.io/embed/x25yop4x5w?fontsize=14
感谢您的帮助
酶 context
影响遗留 React 上下文,而不是现代上下文 API。它应该被嘲笑:
mount(<MyContext.Provider value={{foo: 987}}><ChildComponent/></MyContext.Provider>)
并断言:
expect(wrapper.find('h2').text()).toBe('Context value: 987');
我用来测试需要安装在上下文提供程序树中的组件的方法是使用 wrappingComponent
和 wrappingComponentProps
options for mount.
这样可以确保mount(根组件)的return值仍然是你要测试的组件(并且仍然会支持只对根组件起作用的APIs/options,比如setProps
).
mount(<MyComponent />, {
wrappingComponent: MyContext.Provider,
wrappingComponentProps: {
value: { foo: 987 },
},
})
我遇到了类似的问题。使用 shallow 不起作用,但后来发现了这种依赖性。安装并实施后,它确实起作用了。
https://www.npmjs.com/package/shallow-with-context
你能做的是
import {withContext} from 'shallow-with-context';
...
test("ChildComponent", () => {
const context = { foo: 987 };
const ChildComponentWithContext = withContext(<ChildComponent />, context);
it("Should test the state setup", () => {
let wrapper = shallow(<ChildComponentWithContext />, { context });
expect(wrapper.state().bar).toEqual(456);
});
it("Should test the context value", () => {
let wrapper = shallow(<ChildComponentWithContext />, { context });
expect(wrapper.state().bar).toEqual(456);
expect(wrapper.context().foo).toEqual(987);
});
});
我第一次尝试使用 React 上下文 API 将信息从主组件传递到孙组件。
首先我创建了一个上下文
const MyContext = React.createContext({});
export default MyContext;
这里是设置上下文值的主要组件
import MyContext from "./MyContext.js";
import ParentComponent from "./ParentComponent.js";
function App() {
return (
<div>
<MyContext.Provider value={{ foo: 12 }}>
<ParentComponent />
</MyContext.Provider>
</div>
);
}
父组件不关心上下文,只是为了创建孙组件
import ChildComponent from "./ChildComponent.js";
class ParentComponent extends Component {
render() {
return (
<div>
Parent
<ChildComponent />
</div>
);
}
}
export default ParentComponent;
这里是读取上下文的子组件
import MyContext from "./MyContext.js";
class ChildComponent extends PureComponent {
constructor() {
super();
this.state = {
bar: 456
};
}
render() {
return (
<div>
<MyContext.Consumer>
{({ foo }) => (
<div>
<h1>Hello I'm the ChildComponent</h1>
<h2>Context value: {foo}</h2>
<h2>State value: {this.state.bar}</h2>
<button onClick={() => this.setState({ bar: foo })}>
Click me
</button>
</div>
)}
</MyContext.Consumer>
</div>
);
}
}
export default ChildComponent;
到目前为止没问题。一切都按预期工作。 ChildComponent 已检索上下文值。
当我尝试用 jest/enzyme 测试它时,问题就来了。我无法设置上下文
it("Should test the context value", () => {
let wrapper = mount(<ChildComponent />, {
context: { foo: 987 }
});
expect(wrapper.state("bar")).toEqual(456);
expect(wrapper.context("foo")).toEqual(987);
});
最后一次期望失败,上下文值为空对象。所以 foo 是未定义的
我在这里重现了这个问题: https://codesandbox.io/embed/x25yop4x5w?fontsize=14
感谢您的帮助
酶 context
影响遗留 React 上下文,而不是现代上下文 API。它应该被嘲笑:
mount(<MyContext.Provider value={{foo: 987}}><ChildComponent/></MyContext.Provider>)
并断言:
expect(wrapper.find('h2').text()).toBe('Context value: 987');
我用来测试需要安装在上下文提供程序树中的组件的方法是使用 wrappingComponent
和 wrappingComponentProps
options for mount.
这样可以确保mount(根组件)的return值仍然是你要测试的组件(并且仍然会支持只对根组件起作用的APIs/options,比如setProps
).
mount(<MyComponent />, {
wrappingComponent: MyContext.Provider,
wrappingComponentProps: {
value: { foo: 987 },
},
})
我遇到了类似的问题。使用 shallow 不起作用,但后来发现了这种依赖性。安装并实施后,它确实起作用了。
https://www.npmjs.com/package/shallow-with-context
你能做的是
import {withContext} from 'shallow-with-context';
...
test("ChildComponent", () => {
const context = { foo: 987 };
const ChildComponentWithContext = withContext(<ChildComponent />, context);
it("Should test the state setup", () => {
let wrapper = shallow(<ChildComponentWithContext />, { context });
expect(wrapper.state().bar).toEqual(456);
});
it("Should test the context value", () => {
let wrapper = shallow(<ChildComponentWithContext />, { context });
expect(wrapper.state().bar).toEqual(456);
expect(wrapper.context().foo).toEqual(987);
});
});