I'm wondering, what's your approach while testing React component using Jest snapshots.
Are you testing every component?
How do you determine if you should create a snapshot for component?
Are you testing whole views or only smaller components (view pieces)?
When should one add props to tested components? Should functions always be mocked using jest.fn() ?
AFAIK, snapshots are more inclined towards "how" your component look like.
My Approach,
Identify the props or state which can alter the presentation of my component. Then I write snapshots for them.
If you cannot achieve setting the state using props, you can use simulate to make the relevant state set and then create a snapshot.
And using jest.fn() in snapshots, doesnot seems much of an advantage as we mock functions when we actually need to unit test whether they were invoked.
Related
What is the difference between Enzyme and React Testing Library and which one should I use for testing in React project?
Enzyme: https://www.npmjs.com/package/enzyme
React Testing Library: https://www.npmjs.com/package/#testing-library/react
In Enzyme, we test the component using the state and props of the component. This generally means that the tests are brittle. Let's say we have already written tests for a component and it is running fine. But what if someone changes the variable name of a state or props in the component, then even if the functionality of the component hasn't changed, our test fails. This kind of behavior demonstrates the brittleness of the test.
Whereas in React Testing Library, we test the component from the user's perspective. Let's say we want to test a drop-down component, we won't test the component according to its state and props. Instead, we use the DOM elements to test it, just how the user interacts with it.
The primary purpose of React Testing Library is to increase confidence in your tests by testing your components in the way a user would use them. Users don't care what happens behind the scenes, they just see and interact with the output. Instead of accessing the components' internal APIs or evaluating their state, you'll get more confidence by writing your tests based on the component output.
At some point, React Testing Library became more widely used than Enzyme.
Currently we are using re-usable component library for our react projects that uses I18nextProvider and passed the i18n instance for the integrating applications. One of the application uses functional components that uses React.memo to handle different use case. For those components, when we change the language it doesn't triggers a re-render. When we manually did a change, then it gets reflected with the new language values. Is that possible to force a re-render for the components that uses React.memo when we change the language?
Whether any one faced similar issues? Does memoize will work for handling translation updates?
You probably did not pass t as memo dependency
const welcome = useMemo(() => <Trans t={t}>Welcome to React</Trans>, [t]);
btw: it might also be you do not need to memo at all...
Project that I'm working on is written in such pattern: each component has index.js with redux mappings and page.js which accepts mappings via props and renders a view.
Component can be huge, it can contain long chains of other smaller components.
Imagine how each component in the chain accepts around 30 props - redux data and redux actions - and then pass them into other components via chain, other components pass them into another components.
Though it's very typical redux situation, I can't live with it and trying to avoid it all the time. I'm trying to use useSelector and useDispatch to work with store, instead of passing dozens of properties I add useSelector right in the place where data is needed.
And all seems to be fine except tests.
I wrote utils for test to mount components inside redux Provider, utils to easily mutate store and to check history of dispatch.
But tests feels more complicated now then before when they just passed props.
It feels that I'm the only person who tries to write tests using redux store.
Is it good idea or bad? Do you know some articles of how to use useSelector and useDispatch and write tests at the same time?
For testability, look into the Container & Presentation Component Pattern. What you basically do is create a component that is purely presentational and maintains next to no state. Everything it displays, it'll get via props. This will let you test the visual elements without worrying about the store.
Next, create a container component that does all of the redux stuff, e.g., fetches, dispatches, etc. and it'll pass the relevant state as props to the presentational component. This will keep your test file size in check and allow you to focus your tests towards different goals while keeping them much simpler. So, your directory will look something like,
coolComponent
coolComponent.js (presentational component)
coolComponent.test.js
index.js (container component)
index.test.js
Testing the store is important as the store and redux determines your data flow. If your data flow doesn't work, it doesn't matter if you have 1000 tests passing elsewhere. You app will fail.
Keep in mind when testing the components that sometimes it doesn't make sense to test the components on their own. If they're only ever used with a parent, I think you can get good coverage testing them with the parent, so don't double your efforts going overboard with testing that way.
I am new to using react hooks api.
Earlier I used to distinguish container components and presentational components.
The project directory structure was according to this distinction.
Container components used to inject store state and action creators to the component through props.
With hooks I have been left clueless how the directory structure should be and whether the hooks should be injected to the component through props or simply imported inside the component.
Should there be a containers and components distinction.
The redux documentation which describes container and presentational components also doesn't seem to be updated for hooks.
Any relevant article or answer is welcome.
About the separation between container components and presentational components, Dan Abramov (working on ReactJs, co-author of Redux and Create React App) wrote this in Presentational and Container Components :
Update from 2019: I wrote this article a long time ago and my views have since evolved. In particular, I don’t suggest splitting your components like this anymore. If you find it natural in your codebase, this pattern can be handy. But I’ve seen it enforced without any necessity and with almost dogmatic fervor far too many times. The main reason I found it useful was because it let me separate complex stateful logic from other aspects of the component. Hooks let me do the same thing without an arbitrary division. This text is left intact for historical reasons but don’t take it too seriously.
As user adel commented, there is now hook equivalents of react-redux stuff. To read redux state, instead of connect, you can use useSelector.
import { useSelector } from 'react-redux'
..
const somePieceOfData = useSelector( state => state.path.to.data )
About container components, you can still seperate your container, using react-redux hook stuff. There is nothing about that with react-redux.
I am also running into the same problem now and was looking for some nice resources in that , but here what I've reached:
There is no big need for the distinction now between UI and container components, you can use custom hooks for the same purpose and you will have fewer lines of code and more readable one. From what I've read (i didn't experiment this yet) but it should have better performance as using functional components including custom hooks inc the app performance.
Take a look at this :
https://dev.to/jenc/discuss-react-hooks-and-life-after-the-container-component-pattern-5bn
There used to be a common use case to full render the component with componentDidMount/componentDidUpdate lifecycles which shallow render doesn't have.
But since enzyme 3+, shallow rendering turned lifecycles on by default, and it simply feels more like real unit test with good isolation between virtual Dom and real Dom. Could anymore share some examples where using mount still shines? (personally don't think HOC necessarily has to be tested by mount)
Full DOM rendering is ideal for use cases where you have components that may interact with DOM APIs or need to test components that are wrapped in higher order components.