2017-06-16 103 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; 
}