【发布时间】:2020-01-24 00:41:27
【问题描述】:
这是完整的错误:
警告:useLayoutEffect 在服务器上什么都不做,因为它 效果无法编码为服务器渲染器的输出格式。 这将导致初始的非水合 UI 和 预期的用户界面。为避免这种情况,useLayoutEffect 只能用于 仅在客户端上呈现的组件
in ForwardRef(ButtonBase) in WithStyles(ForwardRef(ButtonBase)) in ForwardRef(Button) in WithStyles(ForwardRef(Button)) in form in div
我每次运行测试时都会得到它。这是我的测试
/* 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)
})
})
})
我相信它与material-ui组件有关。我已经调查过了,here 上有一个类似的问题,说这个问题与我的项目没有的依赖关系有关。所以我认为这与使用useEffectLayout 的material-ui 组件有关,并且由于某种原因,测试环境不喜欢这样。我用 yarn 和 jest yarn test 运行我的测试来运行测试套件。
【问题讨论】:
-
您可以通过为测试gist.github.com/gaearon/… 指定环境来解决问题,例如
/* @jest-environment node */ -
<LoginForm ... />是 HOC 吗?我也有同样的问题。 -
嘿@skyboyer,感谢您的提示。实际上我之前曾尝试过这样做:将
"jest": { "testEnvironment": "node" }添加到我的package.json 文件中。但它在运行纱线测试时出现了一个新问题:ReferenceError: window is not defined 24 | // }) 25 | > 26 | jest.spyOn(window.localStorage.__proto__, "setItem") | ^ 27 | window.localStorage.__proto__.setItem = jest.fn() 28 | at Object.window (src/setupTests.js:26:12) at Array.forEach (<anonymous>)所以我现在正在研究...... -
好的,所以我在添加节点 jest-environement 时无法摆脱上述
window not defined problem。但是对我有用的是你喜欢@skyboyer的评论,说在我的设置文件中添加import React from "react" React.useLayoutEffect = React.useEffect会起作用。它确实做到了。它很老套,但无论如何。 -
嗨 @LCIII 它不是 HOC
标签: reactjs jestjs material-ui react-hooks react-testing-library