javascript - How to test decorated React component with shallow rendering -


i following tutorial: http://reactkungfu.com/2015/07/approaches-to-testing-react-components-an-overview/

trying learn how "shallow rendering" works.

i have higher order component:

import react 'react';  function withmui(composedcomponent) {   return class withmui {     render() {       return <composedcomponent {...this.props}/>;     }   }; } 

and component:

@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>     );   } } 

and test:

describe('playerprofile component - testing 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 avatar', function() {     let result = this.renderer.getrenderoutput();     console.log(result);     expect(result.type).to.equal(playerprofile);   }); }); 

the result variable holds this.renderer.getrenderoutput()

in tutorial result.type tested like:

expect(result.type).toequal('div');

in case, if log result is:

log: object{type: function playerprofile() {..}, .. }

so changed test like:

expect(result.type).toequal(playerprofile)

now gives me error:

assertion error: expected [function: playerprofile] equal [function: withmui]

so playerprofile's type higher order function withmui.

playerprofile decorated withmui, using shallow rendering, playerprofile component rendered , not it's children. shallow rendering wouldn't work decorated components assume.

my question is:

why in tutorial result.type expected div, in case isn't.

how can test react component decorated higher order component using shallow rendering?

you can't. first let's desugar decorator:

let playerprofile = withmui(     class playerprofile extends react.component {       // ...     } ); 

withmui returns different class, playerprofile class exists in withmui's closure.

this here's simplified version:

var withmui = function(arg){ return null }; var playerprofile = withmui({functioniwanttotest: ...}); 

you pass value function, doesn't give back, don't have value.

the solution? hold reference it.

// no decorator here class playerprofile extends react.component {   // ... } 

then can export both wrapped , unwrapped versions of component:

// must after class declared, unfortunately export default withmui(playerprofile); export let undecorated = playerprofile; 

the normal code using component doesn't change, tests use this:

import {undecorated playerprofile} '../src/playerprofile'; 

the alternative mock withmui function (x) => x (the identity function). may cause weird side effects , needs done testing side, tests , source fall out of sync decorators added.

not using decorators seems safe option here.


Comments