使用 Jest 和 TestUtils 测试 React 表单提交
Posted
技术标签:
【中文标题】使用 Jest 和 TestUtils 测试 React 表单提交【英文标题】:Test React Form Submission With Jest & TestUtils 【发布时间】:2015-01-22 18:50:01 【问题描述】:我在使用 React、TestUtils 和 Jest 测试表单 submit
事件时遇到问题。
我有一个渲染<form>
DOM 元素的组件;同一个组件还有一个处理onSubmit
事件并记录语句的方法。我的目标是模拟 onSubmit
处理程序并断言它已被调用。
form-component.cjsx
module.exports = React.createClass
# Handle form submissions
handleSubmit: (e) ->
console.log 'Make async call'
# Render a form
render: ->
<form onSubmit=@handleSubmit>
<input type="submit" />
</form>
__tests__/test-form-component.coffee
jest
.dontMock '../form-component'
React = require 'react/addons'
TestUtils = React.addons.TestUtils
FormComponent = require '../form-component'
describe 'FormComponent', ->
it 'creates a log statement upon form submission', ->
# Render a FormComponent into the dom
formInstance = TestUtils.renderIntoDocument(<FormComponent />)
# Mock the `handleSubmit` method
formInstance.handleSubmit = jest.genMockFunction()
# Simulate a `submit` event on the form
TestUtils.Simulate.submit(formInstance)
# TestUtils.Simulate.submit(formInstance.getDOMNode()) ???
# I would have expected the mocked function to have been called
# What gives?!
expect(formInstance.handleSubmit).toBeCalled()
相关问题:
Test a React Component function with Jest Test a form with Jest and React JS TestUtils【问题讨论】:
【参考方案1】:您的问题究竟是什么?
React.addons.TestUtils.Simulate.submit()
为我工作。
如果有帮助,我也遇到过类似的情况,我以这种方式测试提交处理程序(使用 sinon.js
、mocha
和 chai
):
var renderDocumentJQuery = $(renderDocument.getDOMNode())
this.xhr = sinon.useFakeXMLHttpRequest();
var requests = this.requests = [];
this.xhr.onCreate = function (xhr)
requests.push(xhr);
;
renderDocumentJQuery.find('input#person_email').val('test@email.com');
React.addons.TestUtils.Simulate.submit(renderDocumentJQuery.find('form')[0]);
var requestFired = requests[0];
this.xhr.restore();
it('should fire an AJAX with the right params', function()
assert.equal(requestFired.requestBody,'campaign_id=123&owner_id=456&person%5Bemail%5D=test%40email.com')
);
it('should fire an AJAX with a POST method', function()
assert.equal(requestFired.method,'POST')
);
it('should fire an AJAX with the correct url', function()
assert.equal(requestFired.url,'url-for-testing')
);
【讨论】:
【参考方案2】:有一个issue with the way React calls event handlers 会导致原始处理函数继续被调用,即使您先尝试模拟它也是如此。
这显然可以通过切换到ES6 class syntax 来创建组件类来避免,但另一个简单的解决方法是让事件处理程序只调用第二个函数并模拟它。例如:
onSubmit: function()
this.handleSubmit(); // extra fn needed for Jest
,
handleSubmit: function()
this.setState(
submitted: true
);
您将设置表单的onSubmit=this.onSubmit
和模拟handleSubmit
而不是onSubmit
。由于这引入了一个看似不必要的额外功能,因此如果您决定这样做,可能值得添加注释以预测以后会尝试“修复它”会破坏测试。
【讨论】:
以上是关于使用 Jest 和 TestUtils 测试 React 表单提交的主要内容,如果未能解决你的问题,请参考以下文章
Jest and React and Typescript & React-Testing-Library 错误