<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                ## 三、官方測試工具庫 我們知道,一個React組件有兩種存在形式:虛擬DOM對象(即`React.Component`的實例)和真實DOM節點。官方測試工具庫對這兩種形式,都提供測試解決方案。 * Shallow Rendering:測試虛擬DOM的方法 * DOM Rendering: 測試真實DOM的方法 ### 3.1 Shallow Rendering Shallow Rendering (淺渲染)指的是,將一個組件渲染成虛擬DOM對象,但是只渲染第一層,不渲染所有子組件,所以處理速度非常快。它不需要DOM環境,因為根本沒有加載進DOM。 首先,在測試腳本之中,引入官方測試工具庫。 ~~~ import TestUtils from 'react-addons-test-utils'; ~~~ 然后,寫一個 Shallow Rendering 函數,該函數返回的就是一個淺渲染的虛擬DOM對象。 ~~~ import TestUtils from 'react-addons-test-utils'; function shallowRender(Component) { const renderer = TestUtils.createRenderer(); renderer.render(<Component/>); return renderer.getRenderOutput(); } ~~~ 第一個[測試用例](https://github.com/ruanyf/react-testing-demo/blob/master/test/shallow1.test.js),是測試標題是否正確。這個用例不需要與DOM互動,不涉及子組件,所以使用淺渲染非常合適。 ~~~ describe('Shallow Rendering', function () { it('App\'s title should be Todos', function () { const app = shallowRender(App); expect(app.props.children[0].type).to.equal('h1'); expect(app.props.children[0].props.children).to.equal('Todos'); }); }); ~~~ 上面代碼中,`const app = shallowRender(App)`表示對`App`組件進行"淺渲染",然后`app.props.children[0].props.children`就是組件的標題。 你大概會覺得,這個屬性的寫法太古怪了,但實際上是有規律的。每一個虛擬DOM對象都有`props.children`屬性,它包含一個數組,里面是所有的子組件。`app.props.children[0]`就是第一個子組件,在我們的例子中就是`h1`元素,它的`props.children`屬性就是`h1`的文本。 第二個[測試用例](https://github.com/ruanyf/react-testing-demo/blob/master/test/shallow2.test.js),是測試`Todo`項的初始狀態。 首先,需要修改`shallowRender`函數,讓它接受第二個參數。 ~~~ import TestUtils from 'react-addons-test-utils'; function shallowRender(Component, props) { const renderer = TestUtils.createRenderer(); renderer.render(<Component {...props}/>); return renderer.getRenderOutput(); } ~~~ 下面就是測試用例。 ~~~ import TodoItem from '../app/components/TodoItem'; describe('Shallow Rendering', function () { it('Todo item should not have todo-done class', function () { const todoItemData = { id: 0, name: 'Todo one', done: false }; const todoItem = shallowRender(TodoItem, {todo: todoItemData}); expect(todoItem.props.children[0].props.className.indexOf('todo-done')).to.equal(-1); }); }); ~~~ 上面代碼中,由于[`TodoItem`](https://github.com/ruanyf/react-testing-demo/blob/master/app/components/TodoItem.jsx)是[`App`](https://github.com/ruanyf/react-testing-demo/blob/master/app/components/App.jsx)的子組件,所以淺渲染必須在`TodoItem`上調用,否則渲染不出來。在我們的例子中,初始狀態反映在組件的`Class`屬性(`props.className`)是否包含`todo-done`。 ### 3.2 renderIntoDocument 官方測試工具庫的第二種測試方法,是將組件渲染成真實的DOM節點,再進行測試。這時就需要調用`renderIntoDocument`?方法。 ~~~ import TestUtils from 'react-addons-test-utils'; import App from '../app/components/App'; const app = TestUtils.renderIntoDocument(<App/>); ~~~ `renderIntoDocument`?方法要求存在一個真實的DOM環境,否則會報錯。因此,測試用例之中,DOM環境(即`window`,?`document`?和?`navigator`?對象)必須是存在的。[jsdom](https://github.com/tmpvar/jsdom)?庫提供這項功能。 ~~~ import jsdom from 'jsdom'; if (typeof document === 'undefined') { global.document = jsdom.jsdom('<!doctype html><html><body></body></html>'); global.window = document.defaultView; global.navigator = global.window.navigator; } ~~~ 將上面這段代碼,保存在`test`子目錄下,取名為?[`setup.js`](https://github.com/ruanyf/react-testing-demo/blob/master/test/setup.js)。然后,修改`package.json`。 ~~~ { "scripts": { "test": "mocha --compilers js:babel-core/register --require ./test/setup.js", }, } ~~~ 現在,每次運行`npm test`,`setup.js`?就會包含在測試腳本之中一起執行。 第三個[測試用例](https://github.com/ruanyf/react-testing-demo/blob/master/test/dom1.test.js),是測試刪除按鈕。 ~~~ describe('DOM Rendering', function () { it('Click the delete button, the Todo item should be deleted', function () { const app = TestUtils.renderIntoDocument(<App/>); let todoItems = TestUtils.scryRenderedDOMComponentsWithTag(app, 'li'); let todoLength = todoItems.length; let deleteButton = todoItems[0].querySelector('button'); TestUtils.Simulate.click(deleteButton); let todoItemsAfterClick = TestUtils.scryRenderedDOMComponentsWithTag(app, 'li'); expect(todoItemsAfterClick.length).to.equal(todoLength - 1); }); }); ~~~ 上面代碼中,第一步是將`App`渲染成真實的DOM節點,然后使用`scryRenderedDOMComponentsWithTag`方法找出`app`里面所有的`li`元素。然后,取出第一個`li`元素里面的`button`元素,使用`TestUtils.Simulate.click`方法在該元素上模擬用戶點擊。最后,判斷剩下的`li`元素應該少了一個。 這種測試方法的基本思路,就是找到目標節點,然后觸發某種動作。官方測試工具庫提供多種方法,幫助用戶找到所需的DOM節點。 * [scryRenderedDOMComponentsWithClass](https://facebook.github.io/react/docs/test-utils.html#scryrendereddomcomponentswithclass):找出所有匹配指定`className`的節點 * [findRenderedDOMComponentWithClass](https://facebook.github.io/react/docs/test-utils.html#findrendereddomcomponentwithclass):與`scryRenderedDOMComponentsWithClass`用法相同,但只返回一個節點,如有零個或多個匹配的節點就報錯 * [scryRenderedDOMComponentsWithTag](https://facebook.github.io/react/docs/test-utils.html#scryrendereddomcomponentswithtag):找出所有匹配指定標簽的節點 * [findRenderedDOMComponentWithTag](https://facebook.github.io/react/docs/test-utils.html#findrendereddomcomponentwithtag):與`scryRenderedDOMComponentsWithTag`用法相同,但只返回一個節點,如有零個或多個匹配的節點就報錯 * [scryRenderedComponentsWithType](https://facebook.github.io/react/docs/test-utils.html#scryrenderedcomponentswithtype):找出所有符合指定子組件的節點 * [findRenderedComponentWithType](https://facebook.github.io/react/docs/test-utils.html#findrenderedcomponentwithtype):與`scryRenderedComponentsWithType`用法相同,但只返回一個節點,如有零個或多個匹配的節點就報錯 * [findAllInRenderedTree](https://facebook.github.io/react/docs/test-utils.html#findallinrenderedtree):遍歷當前組件所有的節點,只返回那些符合條件的節點 可以看到,上面這些方法很難拼寫,好在還有另一種找到DOM節點的替代方法。 ### 3.3 findDOMNode 如果一個組件已經加載進入DOM,`react-dom`模塊的`findDOMNode`方法會返回該組件所對應的DOM節點。 我們使用這種方法來寫第四個[測試用例](https://github.com/ruanyf/react-testing-demo/blob/master/test/dom2.test.js),用戶點擊Todo項時的行為。 ~~~ import {findDOMNode} from 'react-dom'; describe('DOM Rendering', function (done) { it('When click the Todo item,it should become done', function () { const app = TestUtils.renderIntoDocument(<App/>); const appDOM = findDOMNode(app); const todoItem = appDOM.querySelector('li:first-child span'); let isDone = todoItem.classList.contains('todo-done'); TestUtils.Simulate.click(todoItem); expect(todoItem.classList.contains('todo-done')).to.be.equal(!isDone); }); }); ~~~ 上面代碼中,`findDOMNode`方法返回`App`所在的DOM節點,然后找出第一個`li`節點,在它上面模擬用戶點擊。最后,判斷`classList`屬性里面的`todo-done`,是否出現或消失。 第五個測試用例,是添加新的Todo項。 ~~~ describe('DOM Rendering', function (done) { it('Add an new Todo item, when click the new todo button', function () { const app = TestUtils.renderIntoDocument(<App/>); const appDOM = findDOMNode(app); let todoItemsLength = appDOM.querySelectorAll('.todo-text').length; let addInput = appDOM.querySelector('input'); addInput.value = 'Todo four'; let addButton = appDOM.querySelector('.add-todo button'); TestUtils.Simulate.click(addButton); expect(appDOM.querySelectorAll('.todo-text').length).to.be.equal(todoItemsLength + 1); }); }); ~~~ 上面代碼中,先找到`input`輸入框,添加一個值。然后,找到`Add Todo`按鈕,在它上面模擬用戶點擊。最后,判斷新的Todo項是否出現在Todo列表之中。 `findDOMNode`方法的最大優點,就是支持復雜的CSS選擇器。這是`TestUtils`本身不提供的。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看