簡體   English   中英

使用React,react-router,jest和enzyme測試狀態更改

[英]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 undefinedFailed 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM