在我的Svelte应用程序中,我试图使用Svelte -test -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秒内被删除-使用延迟检查。
- 测试在请求失败后,元素在某些事件之前没有被删除-这可能是应用程序生命周期的结束,下一个用户交互等。然后,也许您可以监听您选择的任何事件。
时间延迟对我来说是最简单的。但是,无论你决定什么,我认为你必须首先定义它,否则,它太非特异性而无法测试。元素没有被删除(在应用的生命周期?)直到它因其他合法原因被删除?)。