如何为reactjs组件编写测试代码?

时间:2017-07-04 17:51:19

标签: unit-testing reactjs enzyme jest react-boilerplate

我正在尝试为下面的Reactjs组件编写测试代码。这是我在ReactJs中的第一个单元测试,我发现如何正确编写它有些困难,特别是对于下一页中的函数。

我使用 react boilerplate 对整个项目进行了编码。

组件:index.js

    /**
 *
 * ContactUs
 *
 */

import React from 'react'
import SimpleReactValidator from 'simple-react-validator'

import Box from 'grommet/components/Box'
import Form from 'grommet/components/Form'
import FormFields from 'grommet/components/FormFields'
import TextInput from 'grommet/components/TextInput'
import Button from 'grommet/components/Button'
import Heading from 'grommet/components/Heading'

import {injectIntl, FormattedMessage} from 'react-intl'
import messages from './messages'

import MetaTag from '../../components/MetaTag'

class ContactUs extends React.Component {
    constructor(props) {
        super(props)

        this.validator = new SimpleReactValidator()
        this.handleUserInput = this.handleUserInput.bind(this)
        this.submit = this.submit.bind(this)

        this.state = {
            name: '',
            email: '',
            body: '',
        }
    }

    submit(e) {
        e.preventDefault()
        if (this.validator.allValid()) {
            const body = 'Name: ' + this.state.name + '\nEmail: ' + this.state.email + '\n\n' + this.state.body
            document.location.href = 'mailto:sample@samplemail.com?subject=' + this.state.name + '- feedback&body=' + body
        } else {
            this.validator.showMessages()
            this.forceUpdate()
        }
    }

    handleUserInput(e) {
        const name = e.target.name
        const value = e.target.value
        this.setState({
            [name]: value,
        })
    }

    metaData() {
        const {formatMessage} = this.props.intl

        const meta = {
            title: formatMessage(messages.metaTitle),
            desc: formatMessage(messages.metaDescription),
        }
        return (<MetaTag meta={meta}/>)
    }

    render() {
        const {formatMessage} = this.props.intl
        const styles = require('./ContactUs.scss')

        return (
            <Box className={styles.contact_us}>
                {this.metaData()}
                <Heading tag="h2" strong className={styles.title}>
                    <FormattedMessage {...messages.title} />
                </Heading>
                <hr />
                <Box><FormattedMessage {...messages.desc} /></Box>
                <Form onSubmit={this.submit}>
                    <FormFields>
                        <TextInput
                            name="name"
                            placeHolder={formatMessage(messages.name)}
                            onDOMChange={this.handleUserInput}
                        />
                        <Box tag="span" className={styles.error}>
                            {this.validator.message('name', this.state.name, 'required')}
                        </Box>
                        <TextInput
                            name="email"
                            placeHolder={formatMessage(messages.email)}
                            onDOMChange={this.handleUserInput}
                        />
                        <Box tag="span" className={styles.error}>
                            {this.validator.message('email', this.state.email, 'required|email')}
                        </Box>
                        <textarea name="body" className={styles.textarea} onDOMChange={this.handleUserInput}/>
                        <Button type="submit" primary plain onClick={this.submit} className={styles.post}>
                            <FormattedMessage {...messages.button} />
                        </Button>
                    </FormFields>
                </Form>
            </Box>
        )
    }
}

ContactUs.contextTypes = {
    intl: React.PropTypes.object.isRequired,
}

export default injectIntl(ContactUs)

组件测试文件:index.test.js 它是从框架本身派生的默认页面。

    import React from 'react'
import {mount, render, shallow} from 'enzyme'
import {expect} from 'chai'

import {shallowWithIntl} from '../../../../internals/testing/intl.js'

import ContactUs from '../index.js'

const wrapper = shallow(<ContactUs />);

describe('ContactUs', () => {

    it("should send mail mailto:test@gmail.com?subject=name of sender-feedback&body=mesagebody when name,email and body available", () => {
      const renderedComponent = shallowWithIntl(<ContactUs />);
      const name = 'testname';
      const body = 'testbody';
      const email = 'speakerswire.dev@gmail.com';

      const loc = 'mailto:speakerswire.dev@gmail.com?subject=' + name + '- feedback&body=' + body

      const realBody = 'Name: ' + name + '\nEmail: ' + email + '\n\n' + body
      document.location.href = 'mailto:speakerswire.dev@gmail.com?subject=' + name + '- feedback&body=' + realBody

      const expected = 'mailto:speakerswire.dev@gmail.com?subject=testname-feedback&body=testbody'
      const actual = renderedComponent.instance().loc;

      expect(actual).be(expected);
    })

})

拜托,有人帮助我。

0 个答案:

没有答案