2017-06-16 105 views
2

問題:玩笑:嘲諷console.error - 測試失敗

我有一個簡單的陣營組件我用學習來測試用玩笑和酶組分。在我使用道具時,我添加了prop-types模塊來檢查開發中的屬性。 prop-types使用console.error來警告什麼時候強制道具不通過或道具是錯誤的數據類型。

我想模擬console.error來計算我在丟失/錯誤類型的道具中傳遞的被調用的次數prop-types

使用這種簡化的例子組件和測試,我預計這兩個測試表現爲這樣:

  1. 有0/2需要道具的第一個測試應該抓住模擬調用兩次。
  2. 用1/2所需道具進行的第二次測試應該抓住被稱爲一次的模擬。

相反,我得到這樣的:

  1. 第一個測試運行成功。
  2. 第二次測試失敗,抱怨模擬功能被稱爲零次。
  3. 如果我交換測試順序,第一個工作,第二個失敗。
  4. 如果我將每個測試分成一個單獨的文件,兩個工作。
  5. console.error輸出被抑制,所以很明顯它被嘲笑。

我確定我錯過了一些明顯的東西,比如清除模擬錯誤或其他。

當我對輸出函數的模塊使用相同的結構,調用console.error一些任意的次數時,事情就會起作用。

這是當我測試酶/反應,我第一次測試後,我打這個牆。

樣品App.js:

import React, { Component } from 'react'; 
import PropTypes from 'prop-types'; 

export default class App extends Component { 

    render(){ 
    return(
     <div>Hello world.</div> 
    ); 
    } 
}; 

App.propTypes = { 
    id : PropTypes.string.isRequired, 
    data : PropTypes.object.isRequired 
}; 

樣品App.test.js

import React from 'react'; 
import { mount } from 'enzyme'; 
import App from './App'; 

console.error = jest.fn(); 

beforeEach(() => { 
    console.error.mockClear(); 
}); 

it('component logs two errors when no props are passed',() => { 
    const wrapper = mount(<App />); 
    expect(console.error).toHaveBeenCalledTimes(2); 
}); 

it('component logs one error when only id is passed',() => { 
    const wrapper = mount(<App id="stringofstuff"/>); 
    expect(console.error).toHaveBeenCalledTimes(1); 
}); 

最後一點:是啊,這是更好地編寫組件生成一些用戶當道具丟失時友好的輸出,然後測試。但是一旦我發現這種行爲,我想弄清楚我做錯了什麼,以此來提高我的理解。顯然,我錯過了一些東西。

回答

2

你沒有錯過任何東西。有關於缺少錯誤/警告消息的已知問題(https://github.com/facebook/react/issues/7047)。

如果你切換你的測試用例('...當只有id被傳遞' - 'fisrt',...當沒有道具通過時 - 第二個),並在你的測試用例中添加這樣的內容,你可以看到關於缺少id的消息在第二個測試中沒有被觸發。

2

鑑於@DLyman解釋的行爲,你可以做這樣的:

describe('desc',() => { 
    let spy = spyConsole(); 

    it('x',() => { 
     // [...] 
    }); 

    it('y',() => { 
     // [...] 
    }); 

    it('throws [...]',() => { 
     shallow(<App />); 
     expect(console.error).toHaveBeenCalled(); 
     expect(spy.console.mock.calls[0][0]).toContain('The prop `id` is marked as required'); 
    }); 
}); 

function spyConsole() { 
    // https://github.com/facebook/react/issues/7047 
    let spy = {}; 

    beforeAll(() => { 
     spy.console = jest.spyOn(console, 'error').mockImplementation(() => {}); 
    }); 

    afterAll(() => { 
     spy.console.mockRestore(); 
    }); 

    return spy; 
}