使用react-test-renderer/shallow寫測試


我的項目是采用react + ts來寫的,項目中要寫單元測試,於是采用了Jest庫,  主要用的package有

react-test-renderer

react-test-renderer/shallow

@jest/globals

這里展示shallow的用法,主要用來測導航欄組件

 1 import {createRenderer} from "react-test-renderer/shallow";
 2 import {afterEach, beforeEach, describe, expect, it} from "@jest/globals";
 3 import * as React from "react";
 4  
 5  
 6 describe("render element", () => {
 7  //創建renderer
 8   const wrapper = createRenderer();
 9   let elements: JSX.Element;
10   let leftEle: JSX.Element;
11   let linkContainerEle: JSX.Element;
12   beforeEach(() => {
13     //淺渲染組件
14     wrapper.render(renderFrame());
15 
16     //獲取到最外層的某個元素
17     elements = wrapper.getRenderOutput();
18 
19 
20 
21     //get element
22     leftEle = elements.props.children[0];
23 
24 
25 
26     //get element
27     linkContainerEle = elements.props.children[1];
28   });
29 
30 
31 
32   afterEach(() => {
33     wrapper.unmount();
34   });
35 
36 
37   //這里是測渲染,(Link的to屬性)
38   it("the link of logo icon connect to 'testNav'", () => {
39     //get element
40     const logoIconEle = leftEle.props.children[0];
41     expect(logoIconEle.props.to).toBe("testNav");
42   });
43  
44   // 這里測事件---這個方法可行,但是原理我不是很明白
45   it("when click 'icon', hidden/display box", () => {
46     // mock event
47     const event: {nativeEvent: {stopImmediatePropagation: () => void}} = {
48       nativeEvent: {
49         stopImmediatePropagation: () => {
50           // do nothing
51         },
52       },
53     };
54     // simulate user action, click icon
55   //不直接找到icon元素,調用它的點擊事件,而是找到點擊事件對應的函數,直接調這個函數
56     wrapper.getMountedInstance()["changeShowBox"](event);
57 
58 
59 
60     // so state showBox become true
61     expect(wrapper.getMountedInstance()["state"]["showBox"]).toBeTruthy;
62   });
63 
64 
65 
66 
67  });
View Code

 

上述兩個方法只能說可行,具體的用法可能不太正確

 

 

下面展示react-test-renderer測導航欄組件的用法(個人比較推薦)

 1 describe("TopNavigationBar - lineFilter", () => {
 2   //渲染導航欄父組件
 3   const renderFrames = (lineFilterArr?: string[]) => (
 4     <HashRouter>
 5       <TopNavigationBar
 6         routePath={routePath}
 7         history={history}
 8         location={location}
 9         match={match}
10         lineFilters={lineFilterArr ? lineFilterArr : ["line1", "line2"]}
11       />
12     </HashRouter>
13   );
14 
15   let newFrame: ReactTestRenderer;
16   let topNavComponent: ReactTestInstance;
17   beforeEach(() => {
18     //調用渲染方法
19     newFrame = create(renderFrames());
20     // 找到導航欄組件
21     topNavComponent = newFrame.root.findByType(TopNavigationBar);
22   });
23   afterEach(() => {
24     newFrame.unmount();
25   });
26 
27   it("render state 'lineFilter'", () => {
28 //找到state中對應的值
29     const stateLineFilters = topNavComponent.instance.state.lineFilters;
30     const received: ILineFilter[] = [
31       {
32         text: "line1",
33         selected: false,
34       },
35       {
36         text: "line2",
37         selected: false,
38       },
39     ];
40     // render state lineFilter
41     expect(JSON.stringify(stateLineFilters)).toEqual(JSON.stringify(received));
42   });
43 
44   it("when select on item, change state 'lineFilter'", () => {
45     // simulate select one item
46     const selectedLine: ILineFilter = {
47       text: "line1",
48       selected: false,
49     };
50 //找到該元素,調用元素綁定的onClick方法
51     topNavComponent.findAllByProps({className: "tes-topNavBar-line"})[0].props.onClick(selectedLine);
52 
53     const lineFilterArr: ILineFilter[] = topNavComponent.instance.state.lineFilters;
54     lineFilterArr.forEach((e) => {
55       // so this item 'selected' property changed
56       if (e.text === selectedLine.text) expect(e.selected).toBeTruthy;
57     });
58   });
59 
60   it("when props 'lineFilters' changed, change state 'lineFilters'", () => {
61     // 修改父級傳入的API lineFilters
62     newFrame.update(renderFrames(["11", "22"]));
63     const topNav = newFrame.root.findByType(TopNavigationBar);
64     const stateLineFilters = topNav.instance.state.lineFilters;
65     const receivedArr: ILineFilter[] = [
66       {
67         text: "11",
68         selected: false,
69       },
70       {
71         text: "22",
72         selected: false,
73       },
74     ];
75     //測試state,渲染對應的值
76     expect(JSON.stringify(stateLineFilters)).toEqual(JSON.stringify(receivedArr));
77   });
78 });

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM