我遇到的问题是模拟常量在jest.doMock
.
看看最小的 repo。
我试过用mock
而不是doMock
- 同样的错误。
应用程序.test.js
import React from "react"
import App from './App'
import '@testing-library/jest-dom'
import { render } from "@testing-library/react";
describe('testing app.js', () => {
// To reset manually mocked values
beforeEach(() => {
jest.resetModules()
});
test("SET CONSTANT TO 1", () => {
jest.doMock('./myConstants.js', () => ({
CONSTANT: {
NUMBER: 1
}
}))
const { getByText, getByLabelText } = render(<App />)
expect(getByText('1')).toBeInTheDocument()
})
test("SET CONSTANT TO 3", () => {
jest.doMock('./myConstants.js', () => ({
CONSTANT: {
NUMBER: 3
}
}))
const { getByText, getByLabelText } = render(<App />)
expect(getByText('3')).toBeInTheDocument()
})
})
应用程序.js
import React from "react"
import { CONSTANT } from './myConstants.js'
console.log(CONSTANT)
const App = () => {
return (
<div>
{CONSTANT.NUMBER}
</div>
);
}
export default App;
myConstants.js:
export const CONSTANT = { NUMBER: 2 }
上面的两个测试都失败了。其中之一的输出是:
TestingLibraryElementError: Unable to find an element with the text: 3. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.
<body>
<div>
<div>
2
</div>
</div>
</body>
29 | }))
30 | const { getByText, getByLabelText } = render(<App />)
> 31 | expect(getByText('3')).toBeInTheDocument()
扩展解决方案
尽管提供的解决方案运行良好,但我不想重写我要测试的每个组件(通过添加require(...)
)。一种解决方法是使用import("./App").then((module)
import React from "react"
import App from './App'
import '@testing-library/jest-dom'
import { render } from "@testing-library/react";
describe('testing app.js', () => {
// To reset manually mocked values
beforeEach(() => {
jest.resetModules()
});
jest.doMock('./myConstants.js', () => {
return {
__esModule: true,
CONSTANT: {
NUMBER: 1
}
}
})
test("SET CONSTANT TO 1", () => {
// Wait for mock done
return import('./myConstants.js').then((constants) => {
console.log(constants.CONSTANT.NUMBER)
expect(constants.CONSTANT.NUMBER).toBe(1)
import("./App").then((module) => {
const { getByText, getByLabelText } = render(<module.default />)
expect(getByText('1')).toBeInTheDocument()
})
})
})
})