Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Testing default props #256

Closed
dannymk opened this issue Jul 12, 2016 · 14 comments
Closed

Testing default props #256

dannymk opened this issue Jul 12, 2016 · 14 comments

Comments

@dannymk
Copy link

dannymk commented Jul 12, 2016

Is there an example anywhere on how to test default properties?

'use strict';
import React from 'react';
require('styles//Dan.less');
class DanComponent extends React.Component {
  render() {
    return (
      
{this.props.name} is now here!
); } } DanComponent.displayName = 'DanComponent'; // Uncomment properties you need DanComponent.propTypes = { name: React.PropTypes.string }; DanComponent.defaultProps = { name: '==blank' }; export default DanComponent; == test 'use strict'; import createComponent from 'helpers/shallowRenderHelper'; import DanComponent from 'components//DanComponent.js'; describe('DanComponent', () => { let component; beforeEach(() => { component = createComponent(DanComponent); }); it('should have its component className as dan-component', () => { expect(component.props.className).to.equal('dan-component'); }); it('Name default property should be ==blank', () => { expect(component.defaultProps.name).to.equal('==blank'); }); });

I understand that 'react-addons-test-utils' may help in this area but I wanted to see if there was an example anywhere on here a la "out of the box".

@sthzg
Copy link
Member

sthzg commented Jul 14, 2016

Hi @dannymk, the shallow render helper lets you make assertions on what your component renders, so it is already one level too deep in the tree to give you access to the outer props.

If you only want to make sure that defaultProps have a certain value you can simply assert this on the component object, without any additional helpers at all:

describe('<DanComponent />', () => {
  it('has "==blank" as a defaultProp for "name"', () => {
    expect(DanComponent.defaultProps.name).to.equal('==blank');
  });
});

If you want to assert things on the rendered component, I suggest you take a look at Enzyme, which is endorsed on the official FB docs like this

Airbnb has released a testing utility called Enzyme, which makes it easy to assert, manipulate, and traverse your React Components' output. If you're deciding on a unit testing library, it's worth checking out: http://airbnb.io/enzyme/

It is one of these packages where skimming over the api just makes you feel happy.

It is also integrated into the V4-generator, which is currently in the makings (you can already install the beta with npm i generator-react-webpack@beta). It has Enzyme setup for you, although you could also simply install it on your existing projects.

To test a (default) prop with Enzyme, you can do this:

import { mount } from 'enzyme';

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

  let component;
  beforeEach(() => {
    component = mount(<DanComponent />);
  });

  describe('when rendering the component', () => {
    it('the defaultProp for "name" should be "==blank"', () => {
      expect(component.prop('name')).to.equal('==blank');
    });
  });
});

@dannymk
Copy link
Author

dannymk commented Jul 15, 2016

Excellent, thank you. I can definitely use this on Monday.

@dannymk dannymk closed this as completed Jul 15, 2016
@dannymk
Copy link
Author

dannymk commented Jul 17, 2016

I wish I could just install it into my projects:

ERROR in .//enzyme/build/react-compat.js
Module not found: Error: Cannot resolve module 'react/addons' in /home/daniel/Development/Web/Axis901/node_modules/enzyme/build
@ ./
/enzyme/build/react-compat.js 40:16-39 41:46-69

Installing it from npm (This package is deprecated):

0.9.1-deprecated is the latest of 3 releases

does not look good either :-/

Even after I have confirmed that the react-addons module is installed:

  • npm view react-addons

{ name: 'react-addons',
description: 'Simple packaging of react addons to avoid fiddly 'react/addons' npm module.',
'dist-tags': { latest: '0.9.1-deprecated' },
versions: [ '0.8.0', '0.9.0', '0.9.1-deprecated' ],
maintainers: [ 'strml [email protected]' ],
time:
{ modified: '2015-01-27T13:49:03.165Z',
created: '2014-02-06T15:14:58
...

@weblogixx
Copy link
Member

Hi @dannymk,

you should use react-addons-test-utils directly, react-addons is not an official react module. Maybe it does not provide the testutils in a current version?

It should be enough to:

  • Add enzyme (like you already did)
  • Add react-addons-test-utils directly
  • alter your cfg/test.js to look like this:
'use strict';

let path = require('path');
let srcPath = path.join(__dirname, '/../src/');

let baseConfig = require('./base');

module.exports = {
  devtool: 'cheap-module-source-map',
  module: {
    preLoaders: [
      {
        test: /\.(js|jsx)$/,
        loader: 'isparta-loader',
        include: [
          path.join(__dirname, '/../src')
        ]
      }
    ],
    loaders: [
      {
        test: /\.(png|jpg|gif|woff|woff2|css|sass|scss|less|styl|mp4|ogg|svg)$/,
        loader: 'null-loader'
      },
      {
        test: /\.json$/,
        loader: 'json'
      },
      {
        test: /\.(js|jsx)$/,
        loader: 'babel-loader',
        query: {
          presets: [ 'airbnb' ]
        },
        include: [].concat(
          baseConfig.additionalPaths,
          [
            path.join(__dirname, '/../src'),
            path.join(__dirname, '/../test')
          ]
        )
      }
    ]
  },
  resolve: {
    extensions: [ '', '.js', '.jsx', '.json' ],
    alias: {
      actions: srcPath + 'actions/',
      components: srcPath + 'components/',
      sources: srcPath + 'sources/',
      stores: srcPath + 'stores/',
      styles: srcPath + 'styles/',
      config: srcPath + 'config/' + process.env.REACT_WEBPACK_ENV
    }
  },
  externals: {
    'react/lib/ExecutionEnvironment': true,
    'react/addons': true,
    'react/lib/ReactContext': 'window'
  },
  plugins: []
};

Have a look at the externals section, this is required to get it running. Also, make sure you have the json-loader configured the way you see it above. It is needed by cheerio (a dom traversing lib).

As a next step, make sure to have the following packages installed to make enzyme work correctly:

  • json-loader
  • react-addons-test-utils
  • You should then be able to run a test like this:
import React from 'react';
import { shallow } from 'enzyme';

import MyComponent from 'components/MyComponent';

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

  let component;

  beforeEach(() => {
    component = shallow(<MyComponent />);
  });

  describe('when initializing the component', () => {
    it('should do something', () => {
      throw component.html(); // Debug only
    });
  });
});

Hope this helps.

@dannymk
Copy link
Author

dannymk commented Jul 18, 2016

Much better. Thank you. Configuration in "cfg/test.js" helped.

@ZigaVukcevicDev
Copy link

@weblogixx hi,

I am getting following error:

ERROR in ./test/loadtests.js Module build failed: ReferenceError: [BABEL] /my-path/test/loadtests.js: Unknown option: /my-path/node_modules/enzyme/build/index.js.render.

I can provide content from my files, if this will help somehow.

@weblogixx
Copy link
Member

Hi @be-codified,

could you please provide a link to a repo (if one exists)? Seems like there are some missing webpack deps (e.g. loaders) or there is something missing in the babel config.

@ZigaVukcevicDev
Copy link

Hi @weblogixx thank you for your reply.

Sorry, this is private repo. But I can copy & paste content of files, which ones would you need?

@weblogixx
Copy link
Member

Hi @be-codified,

I would need:

  • The webpack config (at least the test and defaults.js files)
  • Your .babelrc
  • Your package json (at least devDependencies and dependencies)

I hope this should be enough.

@ZigaVukcevicDev
Copy link

Here are the files:

package.json
.babelrc
defaults.js
loadtests.js

If you need anything else, please let me know.

@weblogixx
Copy link
Member

Do you also have a config you run in unit test cases (e.g. cfg/test.js)?

@weblogixx
Copy link
Member

It should look something like this:

'use strict';

const webpack = require('webpack');
let path = require('path');
let srcPath = path.join(__dirname, '/../src/');

let baseConfig = require('./base');

module.exports = {
  devtool: 'inline-source-map',
  module: {
    loaders: [
      {
        test: /\.(png|jpg|gif|mp4|ogg|svg|woff|woff2|md)$/,
        loader: 'null-loader'
      },
      {
        test: /\.json$/,
        loader: 'json'
      },
      {
        test: /\.(js|jsx)$/,
        loader: 'babel-loader',
        include: [].concat(
          baseConfig.additionalPaths,
          [
            path.join(__dirname, '/../src'),
            path.join(__dirname, '/../test')
          ]
        )
      }
    ]
  },
  resolve: {
    extensions: [ '', '.js', '.jsx', '.json' ],
    alias: {
      actions: srcPath + 'actions/',
      components: srcPath + 'components/',
      sources: srcPath + 'sources/',
      stores: srcPath + 'stores/',
      styles: srcPath + 'styles/',
      config: srcPath + 'config/' + process.env.REACT_WEBPACK_ENV
    }
  },
  externals: {
    cheerio: 'window',
    'react/lib/ExecutionEnvironment': true,
    'react/addons': true,
    'react/lib/ReactContext': true
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': '"test"'
    })
  ]
};

Note the externals section. You will also have to install the json-loader (npm install --save-dev json-loader). This is needed for cheerio to work.

Maybe this helps?

@ZigaVukcevicDev
Copy link

I will take a look.

This is my file:

'use strict';

let path = require('path');
let srcPath = path.join(__dirname, '/../src/');

let baseConfig = require('./base');

// Add needed plugins here
let BowerWebpackPlugin = require('bower-webpack-plugin');

module.exports = {
    devtool: 'eval',
    module: {
        preLoaders: [
            {
                test: /\.(js|jsx)$/,
                loader: 'isparta-instrumenter-loader',
                include: [
                    path.join(__dirname, '/../src')
                ]
            }
        ],
        loaders: [
            {
                test: /\.(png|jpg|gif|woff|woff2|css|sass|scss|less|styl)$/,
                loader: 'null-loader'
            },
            {
                test: /\.json$/,
                loader: 'json'
            },
            {
                test: /\.(js|jsx)$/,
                loader: 'babel-loader',
                query: {
                    presets: [ 'enzyme' ]
                },
                include: [].concat(
                    baseConfig.additionalPaths,
                    [
                        path.join(__dirname, '/../src'),
                        path.join(__dirname, '/../test')
                    ]
                )
            },
            // the url-loader uses DataUrls.
            // the file-loader emits files.
            {test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=application/font-woff'},
            {test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=application/octet-stream'},
            {test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file'},
            {test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=image/svg+xml'}
        ]
    },
    resolve: {
        extensions: [ '', '.js', '.jsx' ],
        alias: {
            actions: srcPath + 'actions/',
            helpers: path.join(__dirname, '/../test/helpers'),
            components: srcPath + 'components/',
            sources: srcPath + 'sources/',
            stores: srcPath + 'stores/',
            styles: srcPath + 'styles/',
            config: srcPath + 'config/' + process.env.REACT_WEBPACK_ENV
        }
    },
    plugins: [
        new BowerWebpackPlugin({
            searchResolveModulesDirectories: false
        })
    ]
};

@weblogixx
Copy link
Member

Your extensions should read: extensions: [ '', '.js', '.jsx', '.json' ], not [ '', '.js', '.jsx' ]. Maybe this is all it takes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants