Im working on, on some tests using Jest and fireEvents from react testing library and i came across with this in the docs act wrapper.
I cant understand why events need to be in an act wrapper.
What is the purpose of an act inside there? Can someone provide a simple example?
Thanks
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.
I have a really big application with react(lot of pages, modals, tables,etc) and I'm using redux-saga for managing the state. I have a lote of stores and almost in all the components I use the useSelector method for getting the data from the store and many hooks inside them because of logic.
I want to start testing the application, specially to avoid that the app crashes when there is data undefined, invalid, etc. What library do you recommend me to apply in this case ?
React Testing Library and Jest both have different responsibilities "react testing library" is not a test runner meaning when u enter command npm test or npm run test
it is jest responsibility that collect all the files ending with .test.js and runs each test case and show pass and fail results in your console like below
react testing library provides you function to catch dom element and perform some action below are some of its function
render, fireEvent, waitFor, screen
you can also use Enzyme(another popular testing library) for such function to access dom element
EXTRA: developer often confuse among
jest
react-testing-library
Enzyme
Here Enzyme and react-testing-library are two similar things and alternatives to each other means you can use
enzyme with jest or
react-testing-library with jest
you can also use all three i.e react-testing-library+Enzyme with jest
but you can not use Enzyme and react-testing-library without jest or any other test runner eg: Mocha
where jest(testing-framework) will collect all .test.js files execute all the test cases and put the output in console with detail like how many pass and fail and react-testing-library or enzyme(both are testing library) will help you to perform event and accessing dom element
Common Questions/Confusions for React Developers
What is React Testing Library?
Provides virtual DOMs for tests - Any time we are running tests without a browser, we need to have a virtual DOM so we can do things like click elements and we can see if virtual DOM behaves like it should do (like changing colour of a div on a button click and so on).
How Jest is related to React Testing Library?
Jest is a Javascript testing library(not only for React, but for any JS related framework or library).Jest is a test runner and is responsible for
Finding Tests
Running the tests
Determining whether the tests pass or fail
Both React Testing Library and Jest work together (look at the below image to understand this point
Create-React-App comes with React-Testing-Library by default which also includes Jest, so you don't need to install anything else
What is Enzyme and Mocha?
Enzyme (developed by Airbnb) is an alternative to React-Testing-Library (but not Jest).
Remember from the above screenshot that React-Testing-Library was used to provide virtual DOM. Similar thing in some variations will be done by Enzyme. Enzyme, like RTL is also not a Test Runner, so it might need a runner like Jest.
Mocha is an alternative to Jest
Below combinations are possible
React Testing Library + Jest (React's recommended combination, inbuilt into Create-React-App)
Enzyme + Jest
React Testing Library + Mocha
Enzyme + Mocha
What are the different type of Tests?
Unit Testing
Tests one unit of code at a time. May be a single function or a component without depending on other units
Integration Testing
Tests how multiple units work together. Testing interaction between different functions/units/components
Functional / Behavioural Testing
Functional testing means testing the behaviour of a function/software. We might be testing if the software does the right thing with the particular set of data. That might be an integration test as it might have to interact with different units. So the functional test can be an integration test as well
The functional test can also be a simple unit test. Let's say on a button click, the div turns red. This might be a simple unit test but still it can also be considered as a functional test as it tests for a particular behaviour of CLICK TURNS RED OR NOT
So, the functional test means, not testing the code but testing the behaviour. React-Testing-Library encourages functional tests
Acceptance/End-to-End(E2E) test
This is an End-to-End testing where we need a browser and might also need the server
Popular tools for E2E testing are Cypress and Selenium
Cypress supports only Javascript whereas Selenium supports all popular languages like Java, Python, Ruby, C#, Php, etc. Check - Cypress Vs Selenium
React-Testing-Library doesn't support E2E testing
What is Mocking or Stubbing?
Let me explain this with a scenario. Let's say you have made a website for checking the climate of different cities. This app goes and gets the data (using fetch or axios library) from an external source called Weather-API. You can search for any city and it gives you proper climatic conditions.
Now we need to test this app. Let's say we are writing a unit test to test the function that has this functionality where, when a city is passed as a param it makes a call to an external API (Weather-API in this case), fetches the data and then you can write an expect statement to test if the expected value is equal to the fetched value.
If you take a closer look here, we are actually calling Weather-API in our test as well every time we run the unit test. The disadvantages of this approach are:
We are testing the external API in our app (which is not required)
If we do this, we are wasting our API calls (which are billed in most cases)
We don't need to test external API as Weather-API developers might have already tested it and we need to worry about testing only our app and not the external service
So what's the solution here? The solution is to mimic the response from the external API and use it in our test as the actual value and we can test this against the expected value. This is called Mocking. The reason we are doing this is we already know what the external service gives us back and we don't have to call that API anymore but simply hardcode the values as the actual values.
Reference: Testing React with Jest and React Testing - Bonnie Schulkin
Resources:
To understand the testing and mocking those tests, these are some good free youtube videos
JavaScript Testing - Unit, Integration & e2e - Max, Academind
JavaScript Testing - Mocking Async Code - Max, Academind
React Testing Library Crash Course - Laith Academy
Stackoverflow - What is mocking
To understand in more depth, these are some paid udemy courses
The React Testing Library Bootcamp - Laith Harb
Testing React with Jest and React Testing - Bonnie Schulkin
React Testing Library is not an alternative to Jest, because they need each other and every one of them has a clear task.
Jest is a test runner, which gives you the ability to run tests with Jest from the command line. In addition, Jest offers you functions for test suites, test cases, and assertions.
React Testing Library, in contrast to Jest, is one of the testing libraries to test React components.
If you are using create-react-app, Jest (and React Testing Library) comes by default with the installation. If you are using a custom React setup, you need to install and set up Jest (and React Testing Library) yourself.
You might want to look for more on: https://jestjs.io/docs/en/tutorial-react & https://testing-library.com/docs/react-testing-library/intro/. Also you can follow up for more on issues and disscusions on github channels of the libraries.
JEST
"Jest is a delightful JavaScript Testing Framework with a focus on
simplicity. It works with projects using: Babel, TypeScript, Node,
React, Angular, Vue, and more!"
src: jest
TLDR: Jest allows you to test any of the above without much boilerplate quickly. As a framework, the framework's code calls your test code. Jest looks for changes made to the code to run specific test cases etc. You can write test's for React just using Jest (react documentation)
React Testing Library
"The React Testing Library is a very light-weight solution for testing React components. It provides light utility functions on top of react-dom and react-dom/test-utils, in a way that encourages better testing practices".
src: RTL
TLDR: It is a library (i.e., you call the code). It provides some utilities on top of just using Jest and the default react-dom/jest-utils that help us write tests quickly and with less boilerplate (using multiple act() calls etc.) and closer to real-life use (accessibility)
Use RTL with mock server workers to make your life easier for large projects.
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.
I have a React container-pattern component with some complex logic which manipulates its internal state via this.setState(), etc. I'd like to test both the methods attached to the component which manipulate this state, and the value of this.state before and after they run. I've been poring over the Jest docs and while I see lots of examples of e.g. snapshotting, I specifically need to test this container in the abstract, apart from its display/rendering.
What do folks recommend? What have I missed? :)
Jest is a test runner, mocking framework and has snapshot testing. Snapshot testing tests only the final render.
To test state, I recommend using Jest along with Enzyme. Enzyme allows to simulate actions, inspect state, etc.