我正在开发一个 React 项目,该项目使用 SASS(SCSS 语法)进行样式设置,并使用 Jest 进行单元测试。我在项目中测试样式时遇到问题。这是一个简单的例子:
在 component.js 中(导入单独的样式表)...
const Component = () => {
return (
<div className="greeting">Hello</div>
)
}
Run Code Online (Sandbox Code Playgroud)
在我的 .scss 文件中...
.greeting {
background-color: red;
}
Run Code Online (Sandbox Code Playgroud)
在我的测试文件中...
test('background color should be red', () => {
render(<Component />);
expect(screen.getByText('Hello')).toHaveStyle('background-color: red');
})
Run Code Online (Sandbox Code Playgroud)
测试失败并显示:
expect(element).toHaveStyle()
- Expected
- background-color: red;
Run Code Online (Sandbox Code Playgroud)
但是,如果我使用内联样式 ( <div style={{backgroundColor: red}}>Hello</div>),测试就会通过。
有人遇到过这个问题吗?我还想知道其他人在 Jest 中测试样式的方法(特别是当您的样式保存在单独的 .scss 文件中时)
我正在利用screenfrom@testing-library/dom和renderfrom@testing-library/react进行测试。
我创建了一个简单的计数器应用程序用于学习react testing library。但是当我测试段落是否用{count}文本呈现时,我陷入了困境。
主.jsx
function Main() {
const [Count, setCount] = useState(0);
function handleCount() {
setCount((c) => c + 1);
}
return (
<div>
<h1>Counter App</h1>
<Counter count={Count} />
<Button label="Click me" handleCount={handleCount} />
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
计数器.jsx
function Counter({ count }) {
return <p>{count}</p>;
}
Run Code Online (Sandbox Code Playgroud)
主要规范.jsx
it("should render count", () => {
render(<Main />);
expect(screen.getByRole("paragraph")).toBeInTheDocument();
});
Run Code Online (Sandbox Code Playgroud)
这个测试还不足以通过。我知道我们可以添加data-testid到<p>DOM 节点,然后我们可以通过getByTestId查询来测试它。但我想知道为什么我上面使用的测试用例getByRole('paragraph')每次都会失败。
如何测试useEffect异步react-testing-libs?
我有:
// in other file
const getData = () => {
return new Promsise(resolve => setTimeout(() => resolve([1, 2, 3]), 5000));
};
const MyComponent = () => {
const [data, setData] = useState([]);
useEffect(() => {
const fetchData = async () => {
const data = await getData();
setData(data);
};
fetchData();
}, []);
return <div>{data.map(item => <span>{item}</span>)}</div>
};
Run Code Online (Sandbox Code Playgroud)
如何测试这个组件?
我现在的测试:
it('MyComponent test', async () => {
await act( async () => {
render(<MyComponent/>, container);
}); …Run Code Online (Sandbox Code Playgroud) 我有一个组件。它有一个按钮。按下按钮后,我使用 setState 函数更改按钮文本(颜色)的样式。当我测试更改的组件时,测试失败,因为更改是异步发生的。我想做一些这里给出的事情(https://testing-library.com/docs/dom-testing-library/api-async/)
const button = screen.getByRole('button', { name: 'Click Me' })
fireEvent.click(button)
await screen.findByText('Clicked once')
fireEvent.click(button)
await screen.findByText('Clicked twice')
Run Code Online (Sandbox Code Playgroud)
但不是等待文本更改。我想等待文字颜色改变。谢谢
这是我的按钮的代码
<Button onPress = {() => {this.setState({state : 1});}}>
<Text style = {style}>Button Text</Text>
</Button>
Run Code Online (Sandbox Code Playgroud)
所以当这个按钮被按下时。state 设置为 1。并且在 render 中:
if(this.state.state === 1) style = style1
else style = style2;
Run Code Online (Sandbox Code Playgroud)
但从日志中可以看出,render是在测试检查样式后调用的。那么如何等待渲染完成后再检查字体颜色是否已更改?
这是测试代码
test('The button text style changes after press', () => {
const {getByText} = render(<Component/>);
fireEvent.press(getByText('button'));
expect(getByText('button')).toHaveStyle({
color : '#ffffff'
});
})
Run Code Online (Sandbox Code Playgroud) 我想测试 api 调用和返回的数据,这些数据应该显示在我的功能组件中。我创建了执行 api 调用的 List 组件。我希望返回的数据显示在组件中,为此我使用了 useState 钩子。组件如下所示:
const List: FC<{}> = () => {
const [data, setData] = useState<number>();
const getData = (): Promise<any> => {
return fetch('https://jsonplaceholder.typicode.com/todos/1');
};
React.useEffect(() => {
const func = async () => {
const data = await getData();
const value = await data.json();
setData(value.title);
}
func();
}, [])
return (
<div>
<div id="test">{data}</div>
</div>
)
}
Run Code Online (Sandbox Code Playgroud)
我写了一个测试,其中我嘲笑了 fetch 方法。我检查 fetch 方法是否已被调用并且它确实发生了。不幸的是,我不知道如何测试响应返回的值。当我尝试 console.log 时,我只是得到 null,我想得到“示例文本”。我的猜测是我必须等待从 Promise 返回的这个值。不幸的是,尽管尝试使用行为和等待方法,但我不知道如何实现它。这是我的测试:
it('test', async () => {
let …Run Code Online (Sandbox Code Playgroud) unit-testing typescript reactjs react-testing-library react-hooks
凭借以用户为中心的方法,我对 RTL 的理解是测试元素排序应该看起来像这样。
const foo = queryByText('foo');
const bar = queryByText('bar');
expect(foo).toBeInTheDocument();
expect(bar).toBeInTheDocument();
expect(foo).toShowBefore(bar); // THIS IS MY PSEUDOCODE
Run Code Online (Sandbox Code Playgroud)
.toShowBefore()但是,我在 RTL 中找不到类似的函数。测试内容按特定顺序显示的正确方法是什么?
我测试的组件呈现出以下内容:
<div>Text<span>span text</span></div>
Run Code Online (Sandbox Code Playgroud)
事实证明,为了测试我拥有的唯一可靠文本是“跨度文本”,但我想获得<div>. 使用 Jest 和 react-testing-library 我可以
await screen.findByText(spanText)
Run Code Online (Sandbox Code Playgroud)
这将返回一个 HTMLElement,但它似乎受到限制,因为我没有任何围绕该元素的上下文。例如,像 parentNode 和 previousSibling 这样的 HTML 方法返回 null 或 undefined。理想情况下,我想获取 parent 的文本内容<div>。知道如何使用 Jest 或 react-testing-library 做到这一点吗?
expect(stuff).toHaveTextContent(text)仅当文本完全匹配时如何才能通过?
.toHaveTextContent("1")如果我正在测试的文本是“100”,则算作匹配
自从使用 @testing-library 进行反应以来,我对这个name属性感到困惑。可以获取渲染按钮的引用,例如:
// <button>Button text</button>
screen.getbyRole("button", {name: /button text/gi})
Run Code Online (Sandbox Code Playgroud)
在这种情况下,名称指的是textNode按钮的内部。围绕输入的故事类似,name可以指的是id或name文本内容。
我目前正在尝试获取像这样呈现的按钮的引用:
<button
aria-label="Close"
class="css-1dliicy"
type="button"
>
Create new
<svg>...</svg>
</button>
Run Code Online (Sandbox Code Playgroud)
并且通过查询找不到该按钮:
const createNewButton = screen.getByRole('button', {
name: /Create new/gi,
});
Run Code Online (Sandbox Code Playgroud)
我显然似乎不知道该name属性的含义,但我似乎找不到有关它的文档。
我的组件有两个类似的表单(两个带有用户名/密码字段的表单)和两个Submit带有文本“提交”的按钮。为了测试提交处理程序,我模拟了表单字段的类型事件,然后单击提交按钮,如下所示:
it('test submit handler', async () => {
const myProvider = ({children}) => <Provider store={store}>{children}</Provider>;
render(<MyComponent />, {wrapper: myProvider});
expect(await screen.findByText('username')).toBeTruthy();
expect(await screen.findByText('password')).toBeTruthy();
await userEvent.type(screen.getByLabelText('username'), 'someusername');
await userEvent.type(screen.getByLabelText('password'), 'somepassword');
fireEvent.click(screen.getByText('Submit'));
await waitFor(() => expect(onSubmit).toBeCalledTimes(1));
});
});
Run Code Online (Sandbox Code Playgroud)
这样做会导致错误TestingLibraryElementError: Found multiple elements with the text: Submit。我查找了这些getBy*方法的文档,看起来它们要么解释了找到的第一个元素,要么在存在多个元素的情况下,它们会抛出错误,这就是这里发生的情况。这两种表单具有不同的处理函数,我想测试这两个函数是否在提交时被调用。访问此Submit按钮第一次出现的好方法是什么?
我尝试用 替换getByText,findByText但这会导致返回Promise { <pending> }, waiting ,这会导致上面提到的相同TestingLibraryElementError错误。
reactjs ×7
jestjs ×4
unit-testing ×2
css ×1
html ×1
javascript ×1
react-hooks ×1
react-native ×1
sass ×1
typescript ×1