我正在遵循此教程:http : //reactkungfu.com/2015/07/approaches-to-testing- react-components-an-overview/
尝试学习“浅渲染”的工作原理。
我有一个更高阶的组件:
import React from 'react'; function withMUI(ComposedComponent) { return class withMUI { render() { return <ComposedComponent {...this.props}/>; } }; }
和一个组件:
@withMUI class PlayerProfile extends React.Component { render() { const { name, avatar } = this.props; return ( <div className="player-profile"> <div className='profile-name'>{name}</div> <div> <Avatar src={avatar}/> </div> </div> ); } }
和一个测试:
describe('PlayerProfile component - testing with shallow rendering', () => { beforeEach(function() { let {TestUtils} = React.addons; this.TestUtils = TestUtils; this.renderer = TestUtils.createRenderer(); this.renderer.render(<PlayerProfile name='user' avatar='avatar'/>); }); it('renders an Avatar', function() { let result = this.renderer.getRenderOutput(); console.log(result); expect(result.type).to.equal(PlayerProfile); }); });
该result变量保存this.renderer.getRenderOutput()
result
this.renderer.getRenderOutput()
在本教程中,result.type测试如下:
result.type
expect(result.type).toEqual('div');
就我而言,如果我登录,result它是:
LOG: Object{type: function PlayerProfile() {..}, .. }
所以我像这样更改了测试:
expect(result.type).toEqual(PlayerProfile)
现在它给了我这个错误:
Assertion Error: expected [Function: PlayerProfile] to equal [Function: withMUI]
所以PlayerProfile类型是高阶函数withMUI。
PlayerProfile
withMUI
PlayerProfile``withMUI使用浅色渲染装饰,仅PlayerProfile组件被渲染,而不是子组件。因此,我假定浅层渲染不适用于装饰的组件。
PlayerProfile``withMUI
我的问题是:
为什么在本教程中为什么result.type应该是div,但在我看来不是。
如何使用浅层渲染测试用高阶组件装饰的React组件?
你不能 首先,让我们稍微对装饰器进行除糖:
let PlayerProfile = withMUI( class PlayerProfile extends React.Component { // ... } );
withMUI返回一个不同的类,因此PlayerProfile类仅存在于withMUI的闭包中。
这是一个简化的版本:
var withMUI = function(arg){ return null }; var PlayerProfile = withMUI({functionIWantToTest: ...});
您将值传递给函数,它不会返回值,您没有值。
解决方案?保持对它的引用。
// no decorator here class PlayerProfile extends React.Component { // ... }
然后,我们可以导出组件的包装版本和未包装版本:
// this must be after the class is declared, unfortunately export default withMUI(PlayerProfile); export let undecorated = PlayerProfile;
使用此组件的普通代码不会更改,但是您的测试将使用以下代码:
import {undecorated as PlayerProfile} from '../src/PlayerProfile';
另一种方法是将withMUI函数模拟为(x) => x(标识函数)。这可能会导致怪异的副作用,需要在测试方面进行,因此当添加装饰器时,您的测试和源可能会不同步。
(x) => x
这里不使用装饰器似乎是安全的选择。