【发布时间】:2022-02-08 00:00:25
【问题描述】:
我最近加入了一个新组织,他们使用大量 CSS 来隐藏/显示元素。
首先,这是一种好的做法吗?我总是(在大多数情况下)使用布尔值显示和隐藏组件以在 dom 中添加或删除它(这也很容易测试)
在尝试使用 @testing-library/react 添加测试时,我发现使用 identity-obj-proxy 模块可以看到这些类。
但是,当尝试测试一个元素是否可见的功能时,这变得很困难,因为我认为编译的代码不会更少。
是否可以编译更少的代码以反映在测试中?
可能与正在使用的类名模块有关吗?
测试失败
it('should open and close when clicked', async () => {
render(
<Collapse
label="Collapse"
testId="collapse-test"
isHidden
>
<div>
<h1>just some demo text</h1>
</div>
</Collapse>
)
const content = screen.getByTestId('collapse-test-content')
expect(content).not.toBeVisible()
userEvent.click(screen.getByTestId('collapse-test-button'))
await waitFor(() => expect(content).toBeVisible())
})
====================result====================
expect(element).not.toBeVisible()
Received element is visible:
<div aria-expanded="false" class="accordionContent contentHidden" data-testid="collapse-test-content" />
38 | )
39 | const content = screen.getByTestId('collapse-test-content')
> 40 | expect(content).not.toBeVisible()
| ^
41 | userEvent.click(screen.getByTestId('collapse-test-button'))
42 | await waitFor(() => expect(content).toBeVisible())
43 | })
组件
import React, { useState } from 'react'
import cn from 'classnames'
import styles from './styles.less'
const AccordionContent = ({ children, hidden, testId }) => {
const displayClass = hidden ? styles.contentHidden : styles.contentBlock
const accordionContentClass = cn(styles.accordionContent, displayClass)
return (
<div
className={ accordionContentClass }
aria-expanded={ !hidden }
data-testid={ `${testId}-content` }
>
{children}
</div>
)
}
const CollapseComponent= ({
isHidden,
onClick,
label,
children,
testId
}) => {
const [hidden, toggleHidden] = useState(isHidden)
const handleOnpress = () => {
toggleHidden((curr) => !curr)
if (onClick) { onClick }
}
return (
<div
className={ styles.accordionWrapper }
data-testid={ testId }
>
<AccordionButton
onPress={ handleOnpress }
buttonLabel={ label }
testId={ testId }
/>
<AccordionContent
hidden={ !!hidden }
testId={ testId }
>
{children}
</AccordionContent>
</div>
)
}
styles.less
.accordion-content {
background-color: @preservica-gray-1;
display: flex;
}
.content-hidden {
display: none;
}
.content-block {
display: flex;
}
jest.config
const config = {
testEnvironment: 'jsdom',
coverageThreshold: {
global: {
statements: 80,
branches: 75,
functions: 75,
lines: 80
}
},
testPathIgnorePatterns: [
"./src/components/atoms/Icons",
"./src/models"
],
coveragePathIgnorePatterns: [
"./src/components/atoms/Icons",
"./src/models"
],
setupFilesAfterEnv: [
"<rootDir>/src/setupTests.ts"
],
moduleNameMapper: {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
"\\.(css|less)$": "identity-obj-proxy",
"^@root(.*)$": "<rootDir>/src$1",
"^common(.*)$": "<rootDir>/src/common$1",
"^translation(.*)$": "<rootDir>/src/translation$1",
"^view(.*)$": "<rootDir>/src/view$1",
"^actions(.*)$": "<rootDir>/src/actions$1",
"^usecases(.*)$": "<rootDir>/src/usecases$1",
"^repository(.*)$": "<rootDir>/src/repository$1",
"^models(.*)$": "<rootDir>/src/models$1",
"^router(.*)$": "<rootDir>/src/router$1",
},
transform: {
"^.+\\.(ts|tsx|js|jsx)$": "ts-jest",
},
snapshotSerializers: [
"enzyme-to-json/serializer"
]
}
【问题讨论】:
-
测试 class,
contentHidden,而不是可见性。 -
我有一个测试可以涵盖这一点,但我想实际测试它是否可见。因为拥有该类名并不意味着内容必须隐藏/显示
标签: javascript reactjs jestjs less testing-library