如何在 svelte 中模拟/模拟笑话测试的子组件事件?

Ste*_* R. 5 jestjs svelte

我想在我的苗条父组件上运行隔离测试(例如OrderSearch)。因此,子组件(例如SearchForm)的行为应该被“模拟”。子组件抛出一个search在父组件中绑定的事件initiateSearch

SearchForm.svelte(子组件 - 不是测试主题 - 应该模拟“提交”的触发)

<script>
  const dispatchEvent = createEventDispatcher()
  
  const submit = () => {
    dispatchEvent('search', {firstName: '42'})
  }
</script>

<div on:click="submit">Submit</div>
Run Code Online (Sandbox Code Playgroud)

OrderSearch.svelte(父组件 - 测试主题)

<script>
  let results = []

  const initiateSearch = (e) => {
    console.log('initiate search with', e)

    // search is started and returns results
    results = [{orderId: 'bar'}]
  }
</script>  
 
<SearchForm on:search="initiateSearch"></SearchForm>

{#each results as order}
  <div data-testid="order">{order.id}</div>     
{/each}
  
Run Code Online (Sandbox Code Playgroud)

到目前为止,在以孤立的方式测试时,我的方法不起作用:OrderSearch.svelte

订单搜索测试.js

const {getAllByTestId, component} = render(Component)

expect(getAllByTestId('order')).toHaveLength(0)

await component.getSubComponent('SearchForm').dispatchEvent('search', {detail: {orderId: 'jonine'}}

expect(getAllByTestId('order')).toHaveLength(1)
Run Code Online (Sandbox Code Playgroud)

drr*_*rrk 1

不要嘲笑孩子的事件。您不需要测试该on:<event>指令是否有效,我假设 Svelte 有相应的测试来确保它有效。您只需测试当针对特定事件执行的代码发生时,您的组件是否以应有的方式响应。fireEvent因此,使用模拟或监视事件处理程序中调用的函数或函数来触发事件。

以下是对组件进行适当更改的示例:

订单搜索.svelte

<script>
  import http from "path/to/some/http/util"
  let results = []

  const initiateSearch = async (e) => {
    // search is started and returns results
    results = await http.fetchSearchResults(e.detail)
  }
</script>  
 
<SearchForm on:search="initiateSearch"></SearchForm>

{#each results as order}
  <div data-testid="order">{order.id}</div>     
{/each}
Run Code Online (Sandbox Code Playgroud)

那么相应的测试可能如下所示:

import mockHttp from "path/to/some/http/util"

jest.mock("path/to/some/http/util")

...

it("calls search endpoint and renders results after fetch resolves", async () => {
   mockHttp.fetchSearchResults.mockResolvedValue([{orderId: 'bar'}])
   const { queryByText, getAllByTestId } = render(Component)
   const submit = queryByText("Submit")

   expect(getAllByTestId('order')).toHaveLength(0)

   await fireEvent.click(submit)

   expect(getAllByTestId('order')).toHaveLength(1)
})
Run Code Online (Sandbox Code Playgroud)