如何模拟一个带有一些附加属性的组件

huangapple go评论65阅读模式
英文:

How to mock a component with some attach properties

问题

I'll provide translations for the code parts you've mentioned:

我使用Jest编写一些测试用例来测试我的应用程序

假设有一个名为`@library`的库我在我的应用程序中使用了一个名为`Input`的组件

在我的应用程序中

```javascript
import { Input } from '@library';

const App = () => {
    return <Input size={Input.SIZE.md} />;
}

假设库中Input的源代码看起来类似于这样:

const Input = () => { // 一些代码 }
    
Input.SIZE = {
  md: 'md',
  lg: 'lg'
}

export { Input };

现在,在我的测试用例中,我想要模拟Input模块,让它变成:

<div data-testid='mock-input' />

当我这样做时:

jest.mock('@library', () => {
  return {
    Input: () => <div data-testid='mock-input' />
  }
})

它会抛出错误,因为它说在模拟的Input中缺少了SIZE

  1. 那么正确的语法应该是什么?当我只想更改Input的渲染部分,但想保留所有关联的值(如SIZE)时,应该怎么做?

  2. 如果我只想在文件中的一个测试用例中将Input组件更改为模拟div,而不是所有测试用例,应该怎么做?


Please note that the translations provided here are for the code parts you mentioned. If you have any specific questions or need further assistance with these code snippets, please let me know.

<details>
<summary>英文:</summary>

im using jest to write some test case for my app

Let&#39;s say there is a library name `@library`, which i use a component name `Input`

in my App

    import {Input} from &#39;@library&#39;;

    const App = () =&gt; {
        return &lt;Input size={Input.SIZE.md} /&gt;
    }


The source code of Input in library assuming looks something like this

    const Input = () =&gt; { // some code }
    
    Input.SIZE = {
      md: &#39;md&#39;,
      lg: &#39;lg&#39;
    }
   
    export {Input};


so now in my test case, i want to mock the Input module, lets say to become 

    &lt;div data-testid=&#39;mock-input&#39; /&gt;

When i do this,

    jest.mock(&#39;@library&#39;, () =&gt; {
      return {
        Input: () =&gt; &lt;div data-testid=&#39;mock-input&#39; /&gt;
      }
    })



It will throw errors because it says it missing SIZE in the mocked Input.

1. But what should be the correct syntax now ? When I only want to change the rendering part of Input, but want to keep all attached values (like SIZE)

1. What if i only want to change the Input component to mock div for only 1 test case in the file, not all test cases, how to do this ?



</details>


# 答案1
**得分**: 1

使用[模拟部分](https://jestjs.io/docs/mock-functions#mocking-partials)。将所有静态属性从原始函数组件复制到模拟函数组件。

例如:

`library.jsx`:
```jsx
const Input = () => <div>原始输入</div>;

Input.SIZE = {
  md: 'md',
  lg: 'lg',
};

export { Input };

index.test.jsx

import React from 'react';
import { render } from '@testing-library/react';
import { Input } from './library';

jest.mock('./library', () => {
  const originalLibrary = jest.requireActual('./library');
  const InputMock = () => <div data-testid="mock-input" />;
  Object.assign(InputMock, originalLibrary.Input);
  return {
    Input: InputMock,
  };
});

describe('76214614', () => {
  test('应该通过', () => {
    const { asFragment } = render(<Input />);
    expect(Input.SIZE).toEqual({ md: 'md', lg: 'lg' });
    expect(asFragment().firstChild).toMatchInlineSnapshot(`
      <div
        data-testid="mock-input"
      />
    `);
  });
});

测试结果:

 PASS  stackoverflow/76214614/index.test.jsx (26.421 s)
  76214614
    ✓ 应该通过 (49 ms)

1 个快照已写入。
快照摘要
 › 从 1 个测试套件中写入 1 个快照。

测试套件:1 通过,1 总共
测试:1 通过,1 总共
快照:1 已写入,1 总共
时间:27.334 秒
英文:

Use Mocking Partials. Copy all static properties from the original function component to the mock function component.

E.g.

library.jsx:

const Input = () =&gt; &lt;div&gt;original input&lt;/div&gt;;

Input.SIZE = {
  md: &#39;md&#39;,
  lg: &#39;lg&#39;,
};

export { Input };

index.test.jsx:

import React from &#39;react&#39;;
import { render } from &#39;@testing-library/react&#39;;
import { Input } from &#39;./library&#39;;

jest.mock(&#39;./library&#39;, () =&gt; {
  const originalLibrary = jest.requireActual(&#39;./library&#39;);
  const InputMock = () =&gt; &lt;div data-testid=&quot;mock-input&quot; /&gt;;
  Object.assign(InputMock, originalLibrary.Input);
  return {
    Input: InputMock,
  };
});

describe(&#39;76214614&#39;, () =&gt; {
  test(&#39;should pass&#39;, () =&gt; {
    const { asFragment } = render(&lt;Input /&gt;);
    expect(Input.SIZE).toEqual({ md: &#39;md&#39;, lg: &#39;lg&#39; });
    expect(asFragment().firstChild).toMatchInlineSnapshot(`
      &lt;div
        data-testid=&quot;mock-input&quot;
      /&gt;
    `);
  });
});

Test result:

 PASS  stackoverflow/76214614/index.test.jsx (26.421 s)
  76214614
    ✓ should pass (49 ms)

1 snapshot written.
Snapshot Summary
1 snapshot written from 1 test suite.

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   1 written, 1 total
Time:        27.334 s

huangapple
  • 本文由 发表于 2023年5月10日 11:00:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/76214614.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定