小编典典

如何使用浅渲染测试装饰的React组件

reactjs

我正在遵循此教程: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.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组件被渲染,而不是子组件。因此,我假定浅层渲染不适用于装饰的组件。

我的问题是:

为什么在本教程中为什么result.type应该是div,但在我看来不是。

如何使用浅层渲染测试用高阶组件装饰的React组件?


阅读 266

收藏
2020-07-22

共1个答案

小编典典

你不能 首先,让我们稍微对装饰器进行除糖:

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(标识函数)。这可能会导致怪异的副作用,需要在测试方面进行,因此当添加装饰器时,您的测试和源可能会不同步。

这里不使用装饰器似乎是安全的选择。

2020-07-22