ReactJS:如何测试组件功能?
ReactJS: How to test a component function?
在我的 meteor 应用程序中,我通过测试我使用的所有方法来进行一些单元测试。我正在做这样的测试 (mocha/chai):
describe('postMessage', () => {
it('should add message', (done) => {
// EXECUTE
const messageId = postMessage.call({ articleId: 123, content: 'Message text' })
// VERIFY
const message = Messenger.findOne(messageId) // get data from mongoDB
expect(message.content).to.equal('Message text') // check for message
expect(message.articleId).to.be.equal(123) // check for articleId
done()
})
})
但这只测试了一部分,即将消息存储到数据库。但是我还要测试写消息提交(blur事件)会不会调用这个方法
这就是我的组件的样子。我需要知道如何对该组件进行测试。因此,在此示例中,我需要测试方法 postMessage
是否在 textarea 元素的模糊事件上被调用,以及 result
的状态值是否获得了 ID。我该怎么做?
组件
class Message extends Component {
addPost (articleId, event) {
const content = event.target.value
postMessage.call(
{ content, articleId },
(error, result) => {
if (error) console.warn(error)
if (result) this.setState({ result })
}
)
}
render () {
return (
<Form>
<TextArea onBlur={this.addPost.bind(this, articleId)} />
</Form>
)
}
}
方法
const postMessage = new ValidatedMethod({
name: 'messenger.insert',
validate: null,
run ({ articleId, content }) {
return Communicator.insert({ content, articleId })
}
})
如果您必须测试它,您可以使用 ref
for TextArea
手动触发模糊事件。您还应该能够存根 Message#addPost
以验证确实在模糊时调用了它。
话虽这么说,但我必须指出这并不是一个特别有价值的测试。您已经测试过 addPost
是否按预期工作。通过测试 addPost
在模糊时被调用,您正在测试两件事:
- React 正确处理事件
- 您将一个函数传递给
onBlur
而不是简单地执行一个函数(对于新手 javascript 开发人员来说这是一个容易犯的错误)
在我看来,这些都不是特别值得测试的东西。
也许 enzyme+sinon
可以帮助您。而且我还会将 blur
行为测试与 addPost
测试分开,这将使它们更易于维护和阅读。
import { shallow } from 'enzyme';
import sinon from 'sinon';
describe('...', () => {
it('Calls Message.addPost function when TextArea.onBlur', () => {
// prepare mock and renders
Message.addPost = sinon.spy();
const wrapper = shallow(<Message />);
const textArea = wrapper.find(TextArea)
// simulate user action
textArea.simulate('blur');
// assert expected outcome
expect(Message.addPost.calledOnce).to.equal(true);
});
})
在我的 meteor 应用程序中,我通过测试我使用的所有方法来进行一些单元测试。我正在做这样的测试 (mocha/chai):
describe('postMessage', () => {
it('should add message', (done) => {
// EXECUTE
const messageId = postMessage.call({ articleId: 123, content: 'Message text' })
// VERIFY
const message = Messenger.findOne(messageId) // get data from mongoDB
expect(message.content).to.equal('Message text') // check for message
expect(message.articleId).to.be.equal(123) // check for articleId
done()
})
})
但这只测试了一部分,即将消息存储到数据库。但是我还要测试写消息提交(blur事件)会不会调用这个方法
这就是我的组件的样子。我需要知道如何对该组件进行测试。因此,在此示例中,我需要测试方法 postMessage
是否在 textarea 元素的模糊事件上被调用,以及 result
的状态值是否获得了 ID。我该怎么做?
组件
class Message extends Component {
addPost (articleId, event) {
const content = event.target.value
postMessage.call(
{ content, articleId },
(error, result) => {
if (error) console.warn(error)
if (result) this.setState({ result })
}
)
}
render () {
return (
<Form>
<TextArea onBlur={this.addPost.bind(this, articleId)} />
</Form>
)
}
}
方法
const postMessage = new ValidatedMethod({
name: 'messenger.insert',
validate: null,
run ({ articleId, content }) {
return Communicator.insert({ content, articleId })
}
})
如果您必须测试它,您可以使用 ref
for TextArea
手动触发模糊事件。您还应该能够存根 Message#addPost
以验证确实在模糊时调用了它。
话虽这么说,但我必须指出这并不是一个特别有价值的测试。您已经测试过 addPost
是否按预期工作。通过测试 addPost
在模糊时被调用,您正在测试两件事:
- React 正确处理事件
- 您将一个函数传递给
onBlur
而不是简单地执行一个函数(对于新手 javascript 开发人员来说这是一个容易犯的错误)
在我看来,这些都不是特别值得测试的东西。
也许 enzyme+sinon
可以帮助您。而且我还会将 blur
行为测试与 addPost
测试分开,这将使它们更易于维护和阅读。
import { shallow } from 'enzyme';
import sinon from 'sinon';
describe('...', () => {
it('Calls Message.addPost function when TextArea.onBlur', () => {
// prepare mock and renders
Message.addPost = sinon.spy();
const wrapper = shallow(<Message />);
const textArea = wrapper.find(TextArea)
// simulate user action
textArea.simulate('blur');
// assert expected outcome
expect(Message.addPost.calledOnce).to.equal(true);
});
})