svelte - 如何使用测试库确保请求失败后不删除元素
问题描述
在我的 Svelte 应用程序中,我尝试使用svelte-testing-library 进行测试,当特定 API 请求(使用msw)成功时删除元素,但在返回错误时不会删除。
检查快乐路径很容易使用
const el = await screen.findByText(/foo/);
await waitForElementToBeRemoved(el);
但是,当请求失败时,检查元素是否被删除的“正确”方法是什么?我可以添加一个自定义 setTimeout(...) 但这似乎不是最佳解决方案。
有没有一种方法可以在做出断言之前轻松确保请求已完成并处理?
Foo.svelte
<script>
let deleted = false;
const deleteFoo = () => {
window
.fetch(`/foo`, {
method: 'DELETE',
})
.then((res) => {
if (res.ok) {
deleted = true;
}
});
};
</script>
{#if !deleted}
<button on:click={deleteFoo}>delete</button>
{/if}
Foo.spec.js
import {render, fireEvent, waitForElementToBeRemoved} from '@testing-library/svelte';
import {server, rest} from './server';
import Foo from './Foo';
test('button hidden on success', async () => {
server.use(
rest.delete('/foo', async (req, res, ctx) => {
return res(ctx.status(200));
})
);
const {getByText, getByRole} = render(Foo, {});
const btn = getByText('delete');
fireEvent.click(btn);
await waitForElementToBeRemoved(btn);
});
test('button visible on error', async () => {
server.use(
rest.delete('/foo', async (req, res, ctx) => {
return res(ctx.status(500));
})
);
const {getByText, getByRole} = render(Foo, {});
const btn = getByText('delete');
fireEvent.click(btn);
await new Promise((r) => setTimeout(r, 10));
await getByText('delete');
});
解决方案
我可以设想一些测试,如果在测试失败后元素被删除,那么成功案例是什么?
我认为你必须重新定义你的测试目标。因此,例如,您可以通过以下一些方法来处理它:
- 正如您所暗示的那样,测试在请求失败后,元素不会在 X 秒内被删除 - 使用延迟进行检查。
- 测试在请求失败后,元素不会在某个事件之前被删除 - 这可能是应用程序生命周期结束、下一次用户交互等。然后,也许您可以监听您选择的任何事件。
时间延迟对我来说似乎最简单。但是,无论你决定什么,我认为你必须先定义它 - 否则,它太不具体而无法测试 - 例如。该元素不会被删除(对于应用程序的生命周期?直到它因其他合法原因被删除?)。
推荐阅读
- javascript - 删除特殊字符 Javascript
- python - Sqlalchemy before_execute 事件 - 如何传递一些外部变量,比如应用程序用户 ID?
- css - 通过画布将滚动事件传递到下面的 div
- mongodb - 猫鼬保存方法不会忘记最后一个模式
- amazon-web-services - 在 AWS Spot 实例上运行 k8s statefulset
- javascript - 当打印页面出现在javascript中时,如何删除“日期”和“无标题”字母?
- mysql - MySQL 5.6.41 errno 1064:使用变量创建 MySQL 查询
- java - Maven Arquillian Junit 测试失败
- python - Keras 卷积自动编码器空白输出
- arrays - 使用perl将json数组转换为csv时出错