Heres the full error:
Warning: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server renderer's output format. This will lead to a mismatch between the initial, non-hydrated UI and the intended UI. To avoid this, useLayoutEffect should only be used in components that render exclusively on the client
in ForwardRef(ButtonBase) in WithStyles(ForwardRef(ButtonBase)) in ForwardRef(Button) in WithStyles(ForwardRef(Button)) in form in div
I get it every time I run my test. Heres my test
/* eslint-disable quotes */ import React from "react" import { shallow, configure } from "enzyme" import LoginForm from "../src/components/LoginForm" import Button from "@material-ui/core/Button" import Adapter from "enzyme-adapter-react-16" import { render, fireEvent, cleanup } from "@testing-library/react" configure({ adapter: new Adapter() }) describe("<LoginForm />", () => { let wrapper let usernameInput let passwordInput let signInButton // Create initial props that get passed into the component const initialProps = { location: { state: { from: { pathname: "/", }, }, }, } // Unit testing describe("Unit tests", () => { // what to do before each test beforeEach(() => { // Render the login form component, pass in props. (Shallow method renders the component without its children, good for unit tests.) wrapper = shallow(<LoginForm {...initialProps} />) usernameInput = wrapper.find("#username") passwordInput = wrapper.find("#password") signInButton = wrapper.find(Button) }) // what to do after each test afterEach(() => { jest.clearAllMocks() }) // UI Integrity test it("should match the snapshot", () => { // snapshots are text references of the html of the rendered component. expect(wrapper.html()).toMatchSnapshot() }) it("should have a username inputs", () => { expect(usernameInput.length).toEqual(1) }) it("should have the expected props on the username field", () => { expect(usernameInput.props()).toEqual({ id: "username", name: "username", value: "", type: "username", onChange: expect.any(Function), required: true, }) }) it("should have a password field", () => { expect(passwordInput.length).toEqual(1) }) it("should have the expected props on the password field", () => { expect(passwordInput.props()).toEqual({ id: "password", name: "password", value: "", type: "password", onChange: expect.any(Function), required: true, }) }) it("should have a submit button", () => { expect(signInButton.length).toEqual(1) }) it("should have the expected props on the button", () => { expect(signInButton.props()).toEqual({ type: "button", variant: "contained", style: expect.objectContaining({ marginTop: "10px", }), onClick: expect.any(Function), children: "Sign In", }) }) }) // Integrations Testing describe("Integrations tests", () => { beforeEach(() => { // Render the login form component, pass in props. (render method renders the component with its children, good for integrations tests, uses react-test-library.) const { getByLabelText, getByText } = render( <LoginForm {...initialProps} /> ) usernameInput = getByLabelText(/Username/i) passwordInput = getByLabelText(/Password/i) signInButton = getByText("Sign In") }) afterEach(cleanup) it("Username text change in onChange event", () => { expect(usernameInput.value).toBe("") fireEvent.change(usernameInput, { target: { value: "James" } }) expect(usernameInput.value).toBe("James") }) it("Password text change in onChange event", () => { expect(passwordInput.value).toBe("") fireEvent.change(passwordInput, { target: { value: "mypassword" } }) expect(passwordInput.value).toBe("mypassword") }) it("Test button submit", () => { const mockLogin = jest.fn() const button = shallow(<Button onClick={mockLogin} />) button.simulate("click") expect(mockLogin.mock.calls.length).toEqual(1) }) }) })
I believe it has something to do with the material-ui component. I've looked into it, theres a similar question on here that says the issue has to do with a dependency that my project does not have. So I think it has to do with the material-ui component using useEffectLayout
and the testing env doesnt like that for some reason. Im running my test with yarn and jest yarn test
to run the test suite.
Option 1: Convert to useEffect Like useLayoutEffect , it won't run on the server, but it also won't warn.
useIsomorphicLayoutEffect() The signature is identical to useEffect, but it fires synchronously after all DOM mutations. That means this hook is a browser hook. But React code could be generated from the server without the Window API.
useLayoutEffect. The signature is identical to useEffect , but it fires synchronously after all DOM mutations. Use this to read layout from the DOM and synchronously re-render. Updates scheduled inside useLayoutEffect will be flushed synchronously, before the browser has a chance to paint.
useEffect doesn't run on server-side render (SSR): useEffect runs after the render.
adding
import React from "react" React.useLayoutEffect = React.useEffect
to my frontend/src/setupTests.js test file is a way to suppress the jest warning. Ultimately, this looks to be an issue with Material-UI components having issues with Jest.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With