Vladyslav Tereshyn
Vladyslav Tereshyn

Reputation: 235

React components testing. Mocha, Enzyme tests. Errors

I am using Mocha and Enzyme tests. Write test in React app at first time. Project is large, so I can't do this frm start. Tell me plz, do I need to add something in webpack.config file and what can I do with errors (below) "Cannot read property 'apply' of undefined" or "Cannot read 'type' of undefined"

enter image description here

Setup.js code:

require('babel-register')();


var jsdom = require('jsdom').jsdom;

var exposedProperties = ['window', 'navigator', 'document'];

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

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

documentRef = document;


process.env.NODE_ENV = 'test';

function noop() {
  return null;
}

require.extensions['.css'] = noop;
require.extensions['.scss'] = noop;
require.extensions['.md'] = noop;
require.extensions['.png'] = noop;
require.extensions['.svg'] = noop;
require.extensions['.jpg'] = noop;
require.extensions['.jpeg'] = noop;
require.extensions['.gif'] = noop;

Test code:

import React from 'react';
import { expect } from 'chai';
import { mount, shallow } from 'enzyme';
import configStore from 'redux-mock-store'

import { defineMessages, FormattedMessage, injectIntl, intlShape } from 'react-intl';

import { LanguageSwitcher } from '../../src/components/LanguageSwitcher';
import { Header } from '../../src/components/Header';
import { SearchBoxRedirect } from '../../src/components/Header';
import { Link } from '../../src/components/Link';
import { Navigation } from '../../src/components/Navigation';


describe('<Header />', () => {
  const mockStore = configStore()

  it('must have an img', () => {
    const intlMockup = {
      formatMessage: () => ('')
    }

    const intlMockupDate = {
      formatDate: () => ('')
    }

    const intlMockupTime = {
      formatTime: () => ('')
    }

    const store = mockStore()


    const wrapper = mount(<Header intl={intlMockup, intlMockupDate, intlMockupTime} />);
    expect(wrapper.find('img')).to.have.length(1);

  });
});

Just in case, code of my simple component:

import React from 'react';
import { defineMessages, FormattedMessage, injectIntl, intlShape } from 'react-intl';
import SearchBoxRedirect from './SearchBoxRedirect';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import s from './Header.css';
import Link from '../Link';
import Navigation from '../Navigation';
import LanguageSwitcher from '../LanguageSwitcher';
import logoUrl from './logo-small.png';
import logoUrl2x from './[email protected]';
import alphaRibbon from './alpha-ribbon.png';

  
export class Header extends React.Component {
  static propTypes = {
    intl: intlShape.isRequired,
  };

  componentDidMount() {
    this.searchbox.refs.queryField.focus();
  }

  render() {
    return (
      <div className={s.root}>
        <div className={s.container}>
          <img className={s.alphaRibbon} src={alphaRibbon} alt="alpha" width="50px" />
          <Link className={s.brand} to="/">
            <img src={logoUrl2x} srcSet={`${logoUrl2x} 2x`} width="67" height="38" alt="8kolo" />
            <span className={s.brandTxt}>
              <FormattedMessage {...messages.brand} />
            </span>
          </Link>
          <Navigation className={s.nav} />
          <div className={s.search}>
            <SearchBoxRedirect
              ref={sb => { this.searchbox = sb; }}
              hitsRoute="/"
              searchOnChange
              placeholder={this.props.intl.formatMessage(messages.searchPlaceholder)}
              prefixQueryFields={['full_name']}
            />
          </div>
          {/* <LanguageSwitcher /> */}
        </div>
        {/* <div className={s.banner}>
          <div className={s.container}>
            <FormattedMessage tagName="p" {...messages.bannerDesc} />
          </div>
        </div>*/}
      </div>
    );
  }
}

export default withStyles(s)(injectIntl(Header));

When I changed import Header from ../Header to 'import {Header} from ...' I get a new errors which on screen below enter image description here

Upvotes: 0

Views: 471

Answers (1)

Ming Soon
Ming Soon

Reputation: 1018

I think the problem is that you are testing the HOC that requires the context from the parent component.

You can always export the pure component alongside the default wrapped component for testing.

Component.js

export class Header extends React.Component {
  ...
}
export default withStyles(s)(injectIntl(Header));

Test code

import { Header } from '../../src/components/Header';
describe('<Header />', () => {
  it('must have an img', () => {
    const intlMockup = {
      formatMessage: () => (''),
      formatDate: () => (''),
      formatTime: () => (''),
    }
    const store = mockStore()
    const wrapper = mount(<Header intl={intlMockup} store={store} />);
    expect(wrapper.find('img')).to.have.length(1);
  });
});

Upvotes: 1

Related Questions