React-testing-library可以通过自定义挂钩呈现的文本测试
在我的React应用程序中,我使用自定义挂钩从带翻译的JSON文件中检索本地化文本。它可以正常工作,但是每当我使用测试图书馆运行期望找到文本的测试时,就找不到文本,因为挂钩在拍摄该组件的快照时尚未触发和填充文本。我想知道是否有一种正确测试的方法?
// locales json file
"LABELS": {
"WELCOME": {
"title": "Welcome"
},
}
//homepage.ts
const homePageText = [
{
variableName: "welcomeText",
key: "LABELS.WELCOME.title",
defaultValue: "Welcome",
},
// usegetLocalizedText自定义hook
import { useMemo, useState } from "react"
import { useSelector } from "react-redux"
import translate from "@localization/translate"
import intl from "react-intl-universal"
export const useGetLocalizedText = (moduleName: string) => {
const [messages, setMessages] = useState([])
;(async () => {
const msgArray = await import(
`@localization/modules/${moduleName}.ts`
).then((msgs) => msgs)
setMessages(msgArray?.default ? msgArray.default : [])
})()
const initComplete: boolean = testInitComplete ? testInitComplete : useSelector(
(state) => state.localization.initComplete
)
const localizedText = useMemo(() => {
const localizedTextTemp: any = {}
messages?.length > 0 &&
messages.forEach((msg) => {
localizedTextTemp[msg.variableName] = translate(
intl,
msg.key,
initComplete,
msg.defaultValue
)
})
return localizedTextTemp
}, [initComplete, messages])
return localizedText
}
export default useGetLocalizedText
//homepage.tsx
const HomePage = () => {
const localizedText = useGetLocalizedText("homePage")
return (
<div>
<span> {localizedText.welcome} </span>
</div>
)
}
当我运行应用程序时,文本会正确显示,但是当我运行测试时,快照显示和空跨度,我会收到错误“ testinglibraryElementErmentErmenterror” :无法找到文本的元素:资金移动模板。
//homepage-test.tsx
import React from "react"
import { customRender } from "../testUtils"
import { screen } from "@testing-library/react"
import HomePage from "@pages/home/"
describe("Home Page", () => {
it("renders without crashing", () => {
customRender(
<HomePage/>
)
expect(screen.getByText("Welcome")).toBeInTheDocument()
})
//快照,
<div> <span> </span> <div>
所以我的问题是,有没有办法运行一个可以找到此文本/创建快照的测试,以便文本在那里?我知道我可以将硬编码文本作为仅用于测试的道具,但不要认为这是一个很好的解决方案。
In my react app, I use a custom hook to retrieve localized text from a JSON file with translations. It works fine, but whenever I use testing-library to run tests expecting to find text, the text cannot be found, because the hook has not fired and populated the text at the time that the snapshot of the component is taken. I am wondering if there is a way to properly test this?
//locales JSON file
"LABELS": {
"WELCOME": {
"title": "Welcome"
},
}
//homepage.ts
const homePageText = [
{
variableName: "welcomeText",
key: "LABELS.WELCOME.title",
defaultValue: "Welcome",
},
//useGetLocalizedText custom hook
import { useMemo, useState } from "react"
import { useSelector } from "react-redux"
import translate from "@localization/translate"
import intl from "react-intl-universal"
export const useGetLocalizedText = (moduleName: string) => {
const [messages, setMessages] = useState([])
;(async () => {
const msgArray = await import(
`@localization/modules/${moduleName}.ts`
).then((msgs) => msgs)
setMessages(msgArray?.default ? msgArray.default : [])
})()
const initComplete: boolean = testInitComplete ? testInitComplete : useSelector(
(state) => state.localization.initComplete
)
const localizedText = useMemo(() => {
const localizedTextTemp: any = {}
messages?.length > 0 &&
messages.forEach((msg) => {
localizedTextTemp[msg.variableName] = translate(
intl,
msg.key,
initComplete,
msg.defaultValue
)
})
return localizedTextTemp
}, [initComplete, messages])
return localizedText
}
export default useGetLocalizedText
//Homepage.tsx
const HomePage = () => {
const localizedText = useGetLocalizedText("homePage")
return (
<div>
<span> {localizedText.welcome} </span>
</div>
)
}
When I run the app, the text appears correctly, but when I run the tests the snapshot shows and empty span and I get the error "TestingLibraryElementError: Unable to find an element with the text: Funds Movement Template. 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."
//homepage-test.tsx
import React from "react"
import { customRender } from "../testUtils"
import { screen } from "@testing-library/react"
import HomePage from "@pages/home/"
describe("Home Page", () => {
it("renders without crashing", () => {
customRender(
<HomePage/>
)
expect(screen.getByText("Welcome")).toBeInTheDocument()
})
//snapshot
<div> <span> </span> <div>
So my question is, is there a way to run a test that will find this text/create the snapshot so the text is there? I know I can pass in hardcoded text as a prop simply for testing but don't think that is a great solution.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不知道
customRender()
助手内部有什么,但我可以猜想您没有提供正确运行钩子所需的东西。也许您需要模拟redux商店以提供
initcomplete
的正确价值?作为解决方案的一部分,我将使用@testing-library/react-钩子测试钩子本身以及钩子是否可以工作,以及是否需要知道钩子在组件的上下文中是否起作用,之后对组件进行测试。如果将钩子经过正确的测试,但是组件仍然会像您提到的那样遇到问题,那么发现错误会更容易。
I don't know what's inside the
customRender()
helper but I can guess that you don't provide something what is needed to run your hook properly.Maybe you need to mock Redux store to provide proper value of
initComplete
?As a part of the solution, I would use @testing-library/react-hooks to test the hook itself and if hook will work and if it will be needed to know if hook works in the component's context test the component afterwards. If hook would be tested properly but component will still make problems like the one you mentioned, it will be much easier to spot the bug.
您不应在测试中直接调用钩子。您应该使用
renderhook
为示例
You should not call hooks directly inside your test. You should use
renderHook
to beExample