0

在我的 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');
});
4

1 回答 1

0

我可以设想一些测试,如果在测试失败后元素被删除,那么成功案例是什么?

我认为你必须重新定义你的测试目标。因此,例如,您可以通过以下一些方法来处理它:

  1. 正如您所暗示的那样,测试在请求失败后,元素不会在 X 秒内被删除 - 使用延迟进行检查。
  2. 测试在请求失败后,元素不会在某个事件之前被删除 - 这可能是应用程序生命周期结束、下一次用户交互等。然后,也许您可​​以监听您选择的任何事件。

时间延迟对我来说似乎最简单。但是,无论你决定什么,我认为你必须先定义它 - 否则,它太不具体而无法测试 - 例如。该元素不会被删除(对于应用程序的生命周期?直到它因其他合法原因被删除?)。

于 2021-03-03T12:20:26.327 回答