-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
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
Failing to mock a method called with a event listener in React/JSX #207
Comments
Facing the same issue... |
Because of the custom internals of React.createClass, this is pretty tricky to solve. We've been thinking about how to make testing React components much easier, and that was one of the many reasons behind embracing standard ES6 class syntax that we just released as 0.13.0-beta. If you write your classes in ES6 form, Jest will be able to mock them correctly. |
Is there any workaround for this issue? I'm running React 0.13.0-beta.1 and things still don't see to be working when I attempt to mock a method on my component instance. EDIT Things seem to be working now that I switched my class to ES6 style (and moved by |
@nickpresta could you maybe post an example that is working for you? i switched to 0.13.0-beta.1 as well, but the original methods are still being called instead of the mocks for me. |
@leebyron or could you maybe provide a short example? |
one way of working around this issue if you don't want to refactor everything would be like this var MyComponent = React.createClass({
getInitialState: function() {
return {
clicked: false
};
},
onButtonClick: function() {
this.handleButtonClick();
},
handleButtonClick: function(){
this.setState({
clicked: true
});
}
render: function() {
return (
<button onClick={this.onButtonClick}>My Button</button>
);
}
}); Then in your test var myComponent = TestUtils.renderIntoDocument(<MyComponent />);
myComponent.handleButtonClick = jest.genMockFunction(); |
Confirmed. If the actual onClick event delegates to another method, /** @jsx React.DOM */
//tests/app/modules/autocompletesearchinput-test.js
jest.dontMock('../../../app/modules/AutocompleteSearchInput.jsx');
var React, TestUtils, FluxxorTestUtils, FluxConstructor, realFlux, fakeFlux, MyComponent, Component;
describe('Testing Autocomplete Search Input', function() {
beforeEach(function() {
React = require('react/addons');
TestUtils = React.addons.TestUtils;
FluxxorTestUtils = require('fluxxor-test-utils');
FluxConstructor = require('../../../app/FluxConstructor.js');
realFlux = FluxConstructor();
fakeFlux = FluxxorTestUtils.fakeFlux(realFlux);
fakeFlux.genMocksForStoresAndActions();
// now all stores and action methods are mocked for testing
MyComponent = require('../../../app/modules/AutocompleteSearchInput.jsx');
Component = TestUtils.renderIntoDocument(<MyComponent flux={fakeFlux} />);
});
it('should have AutocompleteSearchInput class', function() {
var div = TestUtils.findRenderedDOMComponentWithClass(
Component, 'AutocompleteSearchInput');
});
it('when mounted and clicked, should call searchBtnClick', function() {
Component.chooseSuggestion = jest.genMockFunction();
TestUtils.Simulate.click(Component.refs.searchButton.getDOMNode());
expect(Component.chooseSuggestion).toBeCalled();
});
}); <button
onClick={this.searchBtnClick}
className={searchSubmitClasses}
ref="searchButton"> +1 @grahamfowles. thanks. |
Had the same issue, but I don't feel like making a workaround in the code just to allow testing, cause it reduces readability. Isn't there a way to do the workaround only on the test, like injecting a new |
Any update on this issue? 😕 |
In the end I also got it to work using ES6 classes. Unless you want to or have to stick to |
For people that are still going down this road, I suggest that you save yourself some time and start using Mocha, Mockery and Sinon to fully mock and spy on your components and their functions. Until Jest solves these problems, I think you will ultimately end up wanting to try something else. We had a lot of success with Mocha, Mockery, Chai and Sinon in our customized test suite. We now seamlessly run tests on React components, Flux Actions and all of our other components (including react-router components!). We run about 100 tests in less than 10 seconds. Here's a working example of how we run these. https://github.com/adjavaherian/mocha-react |
@codejet I am failing to get it working with ES6 classes. I tried both assigning to the "class" and to the object: LoginForm.handleSubmit = jest.genMockFunction();
const loginForm = TestUtils.renderIntoDocument(
<LoginForm />
);
loginForm.handleSubmit = jest.genMockFunction(); I would love to see your code snippets. |
@zhon you can find my code here: https://github.com/codejet/google-books-search/tree/reactive-element |
I think
should work. We don't have plans to change how createClass works here, but you should be able to mock plain-class functions like this without trouble. |
It just does not work, sooo frustrating. This should be easy. |
@juliankrispel Like what @spicyj mention, this is how i got it to work. Hope it helps. Code: export default class YearField extends React.Component {
render() {
return (
<input type='text' onChange={this.handleAction} ref='field'/>
);
}
handleAction() { ... }
} Test: jest.dontMock(componentPath('YearField'));
const React = require('react/addons');
const TestUtils = React.addons.TestUtils;
const YearField = require('./YearField');
describe('YearField', () => {
YearField.prototype.handleAction = jest.genMockFunction();
let component = TestUtils.renderIntoDocument(element);
it('check change event', () => {
TestUtils.Simulate.change(component.refs.field);
expect(YearField.prototype.handleAction).toBeCalled();
});
}); |
@clouddra that might be the case for es6 classes ... |
so basically if you're still using
it 'should fire autosize', ->
InputComponent.prototype.__reactAutoBindMap.autosize = jest.genMockFunction()
component = TestUtils.renderIntoDocument(<InputComponent value={'hello'}/>)
component.onChange({target: {value: 'Yoyoyo'}})
expect(InputComponent.prototype.__reactAutoBindMap.autosize).toBeCalled() |
@yannickcr I am trying to do it your way, tests failing :( |
I am also looking for a solution to this. However, I am using straight Jasmine, not Jest. |
Using ES6 classes I had to use the solution provided by clouddra. E.g. using MyClass.prototype. Is that the recommended approach or is there still a fix coming here? |
Yes, the recommended solution is to do |
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
When a method is called with an event listener in a React component, the original method is always called and not the mocked one.
Output:
In this example the mock were not called and the original method updated the state. But it works if I call directly
myComponent.onButtonClick
(the mock is called and not the original method).The text was updated successfully, but these errors were encountered: