[英]Testing a state change with React, react-router, jest, and enzyme
我正在嘗試通過測試來驗證有狀態組件的狀態在componentDidMount
是否已適當更改,但由於react-router而遇到了問題。
我正在使用Enzyme,所以我使用mount
來評估生命周期方法,例如componentDidMount
。 通常情況下,這很好......
it("changes state after mount", () => {
const newValue = "new value";
const testPropertyRetriever = () => newValue;
const wrapper = mount(
<StatefulPage
myProperty="initial value"
propertyRetriever={testPropertyRetriever}
/>
);
// componentDidMount should have executed and changed the state's myProperty value
// from "initial value" to "new value"
expect(wrapper.instance().state.myProperty).toEqual(newValue);
});
...但是有問題的組件是有問題的,因為mount
會讓幾個孩子深入,在這種情況下,其中一個后代使用react-router的<Link>
。 因此,運行上述測試會導致錯誤: TypeError: Cannot read property 'history' of undefined
和Failed context type: The context `router` is marked as required in `Link`, but its value is `undefined`.
TypeError: Cannot read property 'history' of undefined
Failed context type: The context `router` is marked as required in `Link`, but its value is `undefined`.
react-router文檔建議將需要上下文的組件(例如,使用react-router的<Link>
)與<MemoryRouter>
或<StaticRouter>
進行測試渲染,但這不起作用,因為這會使組件處於測試一個子而不是ReactWrapper的根,這使得我不可能(據我所知)檢索被測組件的狀態。 (鑒於以上例子......
// ...
const wrapper = mount(
<MemoryRouter>
<StatefulPage
myProperty="initial value"
propertyRetriever={testPropertyRetriever}
/>
</MemoryRouter>
);
expect(wrapper.childAt(0).instance().state.myProperty).toEqual(newValue);
...測試失敗並出現錯誤ReactWrapper::instance() can only be called on the root
。
我很快就知道酶的mount
采用了一個選項參數,允許將上下文傳遞給渲染器,這就是路由器需要的反應。 所以我嘗試刪除路由器包含並提供上下文(基於此答案 )...
//...
const wrapper = mount(
<StatefulPage
myProperty="initial value"
propertyRetriever={testPropertyRetriever}
/>,
{ router: { isActive: true } }
);
expect(wrapper.instance().state.myProperty).toEqual(newValue);
...但是這導致了我開始時關於上下文類型的相同錯誤。 要么我沒有正確地傳遞上下文,我不知道如何將上下文傳遞給需要它的后代,或者沒有辦法(使用這些工具)這樣做。
從這里開始,我一直在尋找有關如何存儲上下文或模擬其中一個組件的詳細信息,但是沒有設法將這些拼圖有效地組合在一起以成功編寫和運行此測試。
當componentDidMount
具有依賴於滿足react-router模塊的上下文的后代時,如何驗證componentDidMount更改的componentDidMount
狀態?
提供給mount功能的路由器定義不完整。
const MountOptions = {
context: {
router: {
history: {
createHref: (a, b) => {
},
push: () => {
},
replace: () => {
}
}
}
}, childContextTypes: {
router: PropTypes.object
}
};
const wrapper = mount(
<StatefulPage
myProperty="initial value"
propertyRetriever={testPropertyRetriever}
/>,
MountOptions
);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.