How to simulate a React component that uses the document object? - reactjs

I am currently writing unit tests for a react component in my application. The react component utilize the DOM api such as document.getElementById().
When I use shallow() or mount() from enzyme, I get an error saying that the document object is null:
I thought that jest already comes with jsdom as a headless browser. How can I fixed this issue to access a fake dom object?

First of all, the component preferably shouldn't use DOM directly because this affects testability and SSR. Rven if it uses, it preferably should use relative queries, not document.
JSDOM is not headless browser but Node.js environment that emulates browser environment.
Jest uses JSDOM by default. document cannot be null, unless it was specifically assigned to it somewhere. If Jest were configured to not use JSDOM, it would throw document is not defined error.
The error states that it is document.getElementById() result that is null, not document.
document.getElementById is supposed to be mocked as any other function:
jest.spyOn(document, 'getElementById').mockReturnValueOnce({ value: '...' });

Document can be simulated as follows:
const sampleHtml = `<html><body><h1>My First Heading</h1><p>My first paragraph.</p></body></html>`;
document.body.innerHTML = sampleHtml;

Related

React Testing Library - possible to render page in browser

I'm testing a UI with the React Testing Library. Wondering if there is any way (including incorporating a separate package) to render the page being created by a test in my browser as I run the test. I'm basically trying to accomplish what happens with Ruby's Capybara gem's save_and_open_page function within my React tests. Is it possible?
You can render a component in the browser by using the testing playground:
import { screen } from "#testing-library/react"
render(<MyComponent />)
// log entire document to testing-playground
screen.logTestingPlaygroundURL()
// log a single element
screen.logTestingPlaygroundURL(screen.getByText('test'))

Can I use Swiper library in React native app?

I am attempting to use this Swiper (https://github.com/nolimits4web/swiper) in my react native mobile app follow this instruction for React Component: https://swiperjs.com/react
So far it's still not working, some errors I saw were:
invariant violation view config getter callback for component 'div' must be a function (received undefined). Make sure to start component names with a capital letter.
Error: Text strings must be rendered within a component.
Just wondering does this library support React Native?
React native doesn't use div so from your error message, likely it is meant for ReactJS web.
Try
https://github.com/leecade/react-native-swiper

How can I get the real DOM in complete browser environment by using Jest?

I want to test something like layout using Jest and Enzyme. But Jest uses JSDOM to simulate the real browser environment.
I can only use Jest in this old project. How can I do it?
Here are some descriptions in JSDOM: https://github.com/jsdom/jsdom#unimplemented-parts-of-the-web-platform

React UnitTest with Jest and Enzyme

I was surprised that many blogs are writing unit tests for React Applications using both Jest and Enzyme.
Cant, we write unit tests for React applications by using the only jest or by the only Enzyme??
If yes, to get a component we use shallow() in enzyme but what we use in Jest?
I think you didn't fully understand the concepts of jest and enzyme.
Jest
TL;DR: Jest is just a test runner on steroids for JavaScript (not just react).
The main functionality of jest is to execute JavaScript tests. It gives you tools to organize your tests, e.g. using describe, it or test blocks. jest comes with a lot of build-in assertions (e.g. expect(actual).toBe(expected)) to help you identifying failing and succeeding tests. On top of that jest comes with additional features, for example it allows you to easily mock functions or even complete modules.
jest is not bound to react in general, but does quite well in combination with react, since it is maintained by facebook just as react itself. So it's basically almost everytime the right joice and also recommended by react.
Enzyme
TL;DR: Collection of utilities to simplify testing/rendering react components.
Technically you don't need Enzyme or any other framework to test react components (only jest). react already exposes react-dom/test-utils but it's really cumbersome to work with those without properly wrapping and simplyfing its API. And that's exactly what enzyme is doing. It basically puts a layer of abstraction over react-dom/test-utils and adds a bunch of utilities, so you don't need to worry about implementing them yourself.
I highly recommend you to look at react-testing-library, an alternative to enzyme, and read "Testing Implementation Details" blog post authored by its founder.
react-testing-library is, like jest, recommended by react.
Jest and Enzyme are not comparable.
Jest don't give you rich API/function to access dom elements like enzyme but it does other important tasks like when you hit command npm test or npm run test jest collect all the test file eg all files ending with .test.js run each test cases within these files and show the result in the console like below its jest responsibility.
Jest is a testing framework or test runner which runs all the test files in one go, enzyme is a utility or library consider this a smaller thing compare to jest it gives many functions to access dom easily like shallow, mount, find, children, etc...

Jest for react-notification

I updated my React project to react-notifactions(https://www.npmjs.com/package/react-notifications)
While writing jest cases, for alert("Login Failed"), I mocked using window.alert = jest.fn().
Now as I updated to react-notifaction like below
NotificationManager.error(Login failed!) how do I mock it
You might want to check if your Jest configuration is aware that it's testing for browsers vs Node.
https://facebook.github.io/jest/docs/en/configuration.html#browser-boolean

Resources