2017-09-04 9 views
2

Je crois que ce que j'essaye de réaliser a été fait de nombreuses fois, mais je ne peux pas le gérer.className renvoie undefined avec les modules CSS Mocha Enzyme & React

Je voudrais juste pouvoir tester si un élément a une certaine classe sur un certain élément.

Splash

import React from 'react'; 
import { NavLink } from 'react-router-dom' 
import Logo from '../shared/logo/index'; 
import * as styles from './style.css'; 

class Splash extends React.Component { 
    render(){ 
    return (
     <div className={styles.indexAppContent}> 
     <NavLink to="/home" className={styles.index}> 
      <Logo /> 
     </NavLink> 
     </div> 
    ); 
    } 
} 

export default Splash; 

style.css

.index { 
    div { 
    color: #FFF; 
    //font-size: 8rem; 
    } 
    position: absolute; 
    left: 50%; 
    top: 50%; 
    display: block; 
    transform: translate3d(-50%, -50%, 0); 
    -webkit-transform: translate3d(-50%, -50%,0); 
    -moz-transform: translate3d(-50%, -50%,0); 
    -ms-transform: translate3d(-50%, -50%,0); 
} 

.indexAppContent { 
    height: 100vh; 
    width: 100vw; 
    position: relative; 
} 

Cependant ceci est la sortie:

{ className: undefined, 
    children: 
    { '$$typeof': Symbol(react.element), 
    type: { [Function: NavLink] propTypes: [Object], defaultProps: [Object] }, 
    key: null, 
    ref: null, 
    props: 
     { to: '/home', 
     className: undefined, 
     children: [Object], 
     activeClassName: 'active', 
     ariaCurrent: 'true' }, 
    _owner: null, 
    _store: {} } } 

Splash

/* eslint-disable object-property-newline */ 
import React from 'react'; 
import ReactTestUtils from 'react-dom/test-utils' 
import { expect } from 'chai'; 
import { NavLink } from 'react-router-dom' 
import { shallow } from 'enzyme'; 

//Splash 
import Splash from '../../../src/components/Splash'; 
import * as styles from '../../../src/components/Splash/style.css'; 

//logo 
import Logo from '../../../src/components/shared/logo'; 


describe('<Splash />',() => { 

    const wrapperSplash = shallow(<Splash/>); 
    const wrapperNavLink = shallow(<NavLink />); 
    const wrapperLogo = shallow(<Logo />); 

    it('must be defined',() => { 
    expect(wrapperSplash).to.be.defined; 
    }); 

    it('should have one logo',() => { 
    expect(wrapperSplash.find(Logo)).to.have.length(1); 
    }) 

    it('should have className',() => { 
    expect(wrapperSplash.first().prop('className')) 
     .to.contain('indexAppContent'); 
    }) 

    it('Logo links to Home',() => { 
    expect(wrapperSplash.find(NavLink).first().props().to) 
     .equals('/Home'); 
    }) 

}); 

test

/* eslint-disable object-property-newline */ 
import React from 'react'; 
import ReactTestUtils from 'react-dom/test-utils' 
import { expect } from 'chai'; 
import { NavLink } from 'react-router-dom' 
import { shallow } from 'enzyme'; 

    it('should have className',() => { 
    console.info(wrapperSplash.first().props()); 
    expect(wrapperSplash.first().prop('className')) 
     .to.contain('indexAppContent'); 
    }) 

Aide test

import path from 'path'; 
import csshook from 'css-modules-require-hook/preset' // import hook before routes 
import routes from '/shared/views/routes' 
import requireHacker from 'require-hacker'; 
import sass from 'node-sass'; 
import {jsdom} from 'jsdom'; 
import injectTapEventPlugin from 'react-tap-event-plugin'; 

injectTapEventPlugin(); 

hook({ 
    extensions: ['.css'], 
    generateScopedName: '[local]', 
    preprocessCss: (data, filename) => 
    sass.renderSync({ 
     data, 
     file: filename, 
     importer: (url) => { 
     if (url.indexOf('~') === 0) { 
      const node_modules_path = path.resolve(__dirname, '../..', 'node_modules'); 

      return { 
      file: path.join(node_modules_path, url.replace('~', '')) 
      }; 
     } 

     return {file: url}; 
     } 
    }).css 
}); 

const fakeComponentString = ` 
    module.exports = require('react').createClass({ 
    render() { 
     return null; 
    } 
    }); 
`; 

requireHacker.hook('svg',() => fakeComponentString); 

// jsdom 
const exposedProperties = ['window', 'navigator', 'document']; 


global.document = jsdom(''); 
global.window = document.defaultView; 
Object.keys(document.defaultView).forEach((property) => { 
    if (typeof global[property] === 'undefined') { 
    global[property] = document.defaultView[property]; 
    } 
}); 

global.navigator = { 
    userAgent: 'node.js' 
}; 
+1

Et 'wrapperSplash' serait ....? –

+0

Désolé les gars, essayait juste de le rendre plus petit. Je l'ai mis à jour maintenant –

+0

et où fournissez-vous l'accessoire 'className' ici? 'const wrapperSplash = shallow ();' ne devrait pas être 'const wrapperSplash = shallow ();'? –

Répondre

0

Vous regardez une prop de ce composant et non l'existence d'un class dans le nœud racine qui a été rendu par ce composant.
Évidemment, vous ne passez pas cet accessoire.
Vous définissez la classe sur l'élément racine de ce composant, ainsi vous devriez vérifier pour l'élément imbriqué qui maintiennent cette classe valeur dans le dom et non l'attribut (prop) className Vous pouvez le faire avec cette syntaxe par exemple:

it('should have class of indexAppContent',() => { 
    expect(wrapperSplash.find('.indexAppContent')).to.have.length(1); 
    }) 
+0

Je vois ce que vous voulez dire, le problème est qu'avec les modules css, la classe n'est jamais sortie comme ce que le style est. Ainsi, la classe rendue ne sera jamais réellement '.indexAppContent'. Je pense que c'est vraiment ce qui se passe –

+0

serait-ce 'index-appContent'? (Attribut cammelCase dans les modules css) –

+0

Il rend à 'src-components-Splash -___ style__indexAppContent ___ 2gYy0' Donc, assez aléatoire, je crois qu'il faut aussi les jours dateTime –