-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
Am I testing connected components correclty? #325
Comments
I would just test You can find a discussion on this here: reduxjs/redux#1534. Hope it helps! |
BOOM! 💥 👯 Thanks @gaearon! |
Change `<Func>` to `<Function>` for consistency
@gaearon How do you test that the state tree looks like you expect? e.g. I change the structure of the state tree by changing the reducer and make sure to change the tests there. Now all my tests pass, but the connected component is broken since it's not mapping the state correctly, anymore. |
@flushentitypacket; write selectors and use them in your // Bad
const mapStateToProps = state => ({
items: state.data.items
})
// Good
import { selectItems } from './store/selectors'
const mapStateToProps = state => ({
items: selectItems(state),
}) Then, test your reducers, actions and selectors together - so your test starts with dispatching an action, and ends with expectations about the selector's output. |
@flushentitypacket @gaearon Question though... so what if you have mapDispatchToProps and you want to check that those methods ARE called in one of your component instance methods. So:
Then in a method within the component:
So we can trigger the So far I have tried many ways to test this involving sinon spys and stubs but I haven't been able to verify that the props method actually gets called. It seems to me that the method spies that I pass in when mounting get overwritten by the Any suggestions on how to check that prop methods inside of |
@cclifford3 I typically export both the connected and unconnected classes for my components. export class MyComponent {
render() {
}
}
export connect(...)(MyComponent) Then I only test the unconnected component. So using say jest and enzyme we can do something like it('calls myFnProp on submit', () => {
const myFnProp = jest.fn()
const component = mounted(<MyComponent myFnProp={myFnProp} />)
component.simulate('submit')
expect(myFnProp).toHaveBeenCalled()
}) ^ I might've gotten some details off there, but I think that gives the general idea. If you really want to test the connected component, I'd say that all you need to do is to test that the props are set correctly, but then you'd be testing react-redux! |
@gaearon and what about short syntax for |
@pokorson : in that case, there's no need to test |
@markerikson but my thought about such tests is to ensure that container play specific role in my UI. I can safely assume react-redux do it's job, (converts and passes action creators to components) and now I want to test if I connected given part of UI with some action. I see it something like this:
It feels like it should be enough to ensure that whole application work correctly? Does it make sense? Or selenium, nightwatch or something similiar is the way to go here? |
Right, but there's a difference between "testing that connected components work as part of the rest of the application", and "testing Beyond that, I don't have a whole lot of advice to offer here :) |
Through the use of |
In connected components, export the base component (not connected), so that it can be tested without re-testing connect. This is possible, because in mapStateToProps, state is accessed via selectors, which can be tested separately. Also, in mapDispatchToProps, actions are defined by action creators that can also be tested separately. Some discussions on this matter: reduxjs/react-redux#325 (comment) reduxjs/redux#1534 https://jsramblings.com/2018/01/15/3-ways-to-test-mapStateToProps-and-mapDispatchToProps.html Ref #14
Couldn't agree more! Testing component logic through connected component results in unnecessary test overhead.
This isn't quite true because you need to verify the correct part of the state/correct action is mapped to the correct prop. e.g. export const TestComponent = ({ permissions }) => (permissions['view-message'] ? 'Hello!' : null);
export default connect(({ auth }) => ({ permissions: auth.userPermissions }))(TestComponent); If I don't test the connected component, then if I make a typo in my mapStateToProps param to p.s. Here's how I would test the props are wired properly: import React from 'react';
import { shallow } from 'enzyme';
import TestContainer, { TestComponent } from './TestContainer';
it('renders TestComponent with approriate props from store', () => {
const userPermissions = {};
// Stubbing out store. Would normally use a helper method. Did it inline for simplicity.
const store = {
getState: () => ({
auth: { userPermissions },
}),
dispatch: () => {},
subscribe: () => {},
};
const subject = shallow(<TestContainer store={store} />).find(TestComponent);
const actual = subject.prop('permissions');
expect(actual).toBe(userPermissions);
}); |
That's a fair nuance to point out. I don't typically find it helpful in the practical sense since it's so easy to catch and identify these sorts of things during "integration tests" (i.e. testing it in a browser, which realistically must be done for any frontend code changes). As far as I can tell, there are only a couple places this could go wrong:
The reason it's nice to unit test a component is that the component may be complex, and so unit tests can streamline the development and especially future development (i.e. code changes) process. I don't see the same value in testing |
in an attempt to make the decorator syntax (which I'm a big fan of lol) more testable I made this: input:
output:
|
Hey folks!
Would like to know if I'm testing correclty my connected component, I've made some search, but still not clear for me and the way I'm doing right now doesn't sounds correclty, thats why I'm asking helping for the jedi council hahaha
The problem:
I want to know if action.fetchPurveyors is being called on fetchData that is passed on mapDispatchToProps:
So, on my unit test I'm doing this:
Is there a better way of doing this? Am I doing an integration test instead of a simple unit test?
Thanks in advance!
The text was updated successfully, but these errors were encountered: