如何在React项目中使用Jest对由事件触发的函数执行单元测试。

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

How to perform unit testing on function invoked by event using Jest in React project

问题

component.js

import { React, useState } from 'React'
import Container from 'react-bootstrap/Container'
import Row from 'react-bootstrap/Row'
import Col from 'react-bootstrap/Col'
import Form from 'react-bootstrap/Form'
import DatePicker from 'react-datepicker'
import Row from 'react-bootstrap/Row'
...
...
function Details() {
  const [initialDate, setInitialDate] = useState(new Date());
  ...
  ...

  return (
    <DatePicker test-id="dPicker" selected={initialDate} onChange={(date) => setInitialDate(date)} />
  )
}

I wanted to unit test the onchange function code for the above datepicker using Jest. What piece of code will help me?

英文:

component.js

    import {React,useState} from &#39;React&#39;
    import Container from &#39;react-bootstrap/Container&#39;
    import Row from &#39;react-bootstrap/Row&#39;
    import Col from &#39;react-bootstrap/Col&#39;
    import Form from &#39;react-bootstrap/Form&#39;
    import DatePicker from &#39;react-datepicker&#39;
    import Row from &#39;react-bootstrap/Row&#39;
    ...
    ...
    function Details (){
    const[initialDate, setInitialDate] = useState(new Date());
    ...
    ...
    
    return(
    &lt;DatePicker test-id=&quot;dPicker&quot; selected = {initialDate} onChange={(date) =&gt; setInitialDate(date)}
    )
    }

I wanted to unit test the onchange function code for above datepicker using Jest . What piece of code will help me?

答案1

得分: 1

We can use ByDisplayValue query to return the input, textarea, or select element that has the matching display value.

Since the initial date state is new Date(), we need to set a mock system date for it so that our test result will be stable no matter when and where (CI/CD server can be any region) running it. We need to use jest.setSystemTime(now?: number | Date) to set the current system time used by fake timers.

E.g.

example.tsx:

import React, { useState } from "react";
import DatePicker from "react-datepicker";

export const Example = () => {
  const [startDate, setStartDate] = useState<Date | null>(new Date());
  return (
    <DatePicker selected={startDate} onChange={(date) => setStartDate(date)} />
  );
};

example.test.tsx:

import { fireEvent, render, screen } from "@testing-library/react"
import '@testing-library/jest-dom';
import React from "react"
import { Example } from "./example"

describe('76034834', () => {
  test('should pass', () => {
    jest
      .useFakeTimers('modern')
      .setSystemTime(new Date('2015-12-20'));
    render(<Example />);
    const input = screen.getByDisplayValue('12/20/2015');
    fireEvent.change(input, { target: { value: new Date('2014-01-02') } });
    expect(screen.getByDisplayValue('01/02/2014')).toBeInTheDocument();
  })
})

Test result:

 PASS  stackoverflow/76034834/example.test.tsx (7.151 s)
  76034834
    ✓ should pass (34 ms)

-------------|---------|----------|---------|---------|-------------------
File         | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------|---------|----------|---------|---------|-------------------
All files    |     100 |      100 |     100 |     100 |                   
 example.tsx |     100 |      100 |     100 |     100 |                   
-------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        7.455 s, estimated 8 s

Package versions:

"react": "^16.14.0",
"react-datepicker": "^4.11.0",
"@testing-library/react": "^11.2.7",
"jest": "^26.6.3",
英文:

We can use ByDisplayValue query to

> Returns the input, textarea, or select element that has the matching display value.

Since the initial date state is new Date(), we need to set a mock system date for it so that our test result will be stable no matter when and where(CI/CD server can be any region) running it. We need to use jest.setSystemTime(now?: number | Date) to

> Set the current system time used by fake timers

E.g.

example.tsx:

import React, { useState } from &quot;react&quot;;
import DatePicker from &quot;react-datepicker&quot;;

export const Example = () =&gt; {
  const [startDate, setStartDate] = useState&lt;Date | null&gt;(new Date());
  return (
    &lt;DatePicker selected={startDate} onChange={(date) =&gt; setStartDate(date)} /&gt;
  );
};

example.test.tsx:

import { fireEvent, render, screen } from &quot;@testing-library/react&quot;
import &#39;@testing-library/jest-dom&#39;;
import React from &quot;react&quot;
import { Example } from &quot;./example&quot;

describe(&#39;76034834&#39;, () =&gt; {
  test(&#39;should pass&#39;, () =&gt; {
    jest
      .useFakeTimers(&#39;modern&#39;)
      .setSystemTime(new Date(&#39;2015-12-20&#39;));
    render(&lt;Example /&gt;);
    const input = screen.getByDisplayValue(&#39;12/20/2015&#39;);
    fireEvent.change(input, { target: { value: new Date(&#39;2014-01-02&#39;) } });
    expect(screen.getByDisplayValue(&#39;01/02/2014&#39;)).toBeInTheDocument();
  })
})

Test result:

 PASS  stackoverflow/76034834/example.test.tsx (7.151 s)
  76034834
    ✓ should pass (34 ms)

-------------|---------|----------|---------|---------|-------------------
File         | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------|---------|----------|---------|---------|-------------------
All files    |     100 |      100 |     100 |     100 |                   
 example.tsx |     100 |      100 |     100 |     100 |                   
-------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        7.455 s, estimated 8 s

package versions:

&quot;react&quot;: &quot;^16.14.0&quot;,
&quot;react-datepicker&quot;: &quot;^4.11.0&quot;,
&quot;@testing-library/react&quot;: &quot;^11.2.7&quot;,
&quot;jest&quot;: &quot;^26.6.3&quot;,

huangapple
  • 本文由 发表于 2023年4月17日 19:45:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/76034834.html
匿名

发表评论

匿名网友

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

确定