react-jest中带有钩子的条件渲染的测试用例

问题描述 投票:0回答:1

我对React世界很陌生。这就是我的反应钩。

export default function MyComponent() {
 const [data, setData] = useState(null);

 useEffect( () => {
   getData().then(setData)
 }, []);

 return(
   data ? <AnotherComponent /> : <LoadingComponent />
 );
}

getData()在另一个带有'fetch'的组件中。

export function getData() {
  return fetch('/api/v2/user').then(response => {
    if(response.status === 200) {
      return response.json()
    } else {
      return {};
    }
  });
}

我正在使用Jest / Enzyme作为测试框架,并希望使用模拟数据测试场景,以便可以测试DOM中不存在LoadingComponent的情况。这是我正在尝试的方法,但似乎未返回模拟值。

const mockValues = {
 data: {}
 count: 10
 result: []
};

jest.mock('../DataService');

const mockService = require('../DataService');
mockService.getData = jest.fn().mockResolvedValue(mockValues);

...
const component = mount(<MyComponent />);
expect(component.html()).toEqual(expect.not.stringContaining('LoadingComponent')); 

[我看到“ mount”工作正常,但似乎未返回模拟值,因此存在LoadingComponent。

reactjs unit-testing jestjs react-hooks enzyme
1个回答
0
投票

这是单元测试解决方案:

index.tsx

import React, { useState, useEffect } from 'react';
import { AnotherComponent } from './AnotherComponent';
import { LoadingComponent } from './LoadingComponent';
import { getData } from './dataService';

export default function MyComponent() {
  const [data, setData] = useState(null);
  useEffect(() => {
    getData().then(setData);
  }, []);
  return data ? <AnotherComponent /> : <LoadingComponent />;
}

AnotherComponent.jsx

export const AnotherComponent = () => <div>AnotherComponent</div>;

LoadingComponent.jsx

export const LoadingComponent = () => <div>LoadingComponent</div>;

dataService.js

export function getData() {
  return fetch('/api/v2/user').then((response) => {
    if (response.status === 200) {
      return response.json();
    } else {
      return {};
    }
  });
}

index.test.jsx

import React from 'react';
import * as DataService from './dataService';
import { mount } from 'enzyme';
import MyComponent from './';
import { act } from 'react-dom/test-utils';

jest.mock('./dataService');

const whenStable = async () => {
  await act(async () => {
    await new Promise((resolve) => setTimeout(resolve, 0));
  });
};

describe('60913717', () => {
  it('should pass', async () => {
    const mockValues = {
      data: {},
      count: 10,
      result: [],
    };
    DataService.getData = jest.fn().mockResolvedValueOnce(mockValues);
    const wrapper = mount(<MyComponent></MyComponent>);
    expect(wrapper.find('LoadingComponent')).toBeTruthy();
    await whenStable();
    expect(wrapper.find('AnotherComponent')).toBeTruthy();
  });
});

带有覆盖率报告的单元测试结果:

 PASS  stackoverflow/60913717/index.test.jsx (28.041s)
  60913717
    ✓ should pass (48ms)

----------------------|---------|----------|---------|---------|-------------------
File                  | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------------------|---------|----------|---------|---------|-------------------
All files             |      80 |       50 |   66.67 |      75 |                   
 AnotherComponent.jsx |     100 |      100 |     100 |     100 |                   
 LoadingComponent.jsx |     100 |      100 |     100 |     100 |                   
 dataService.js       |      20 |        0 |       0 |      20 | 2-4,6             
 index.jsx            |     100 |      100 |     100 |     100 |                   
----------------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        29.721s

源代码:https://github.com/mrdulin/react-apollo-graphql-starter-kit/tree/master/stackoverflow/60913717

© www.soinside.com 2019 - 2024. All rights reserved.