Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 具有异步函数的有状态React组件未能通过Jest测试_Javascript_Reactjs_Unit Testing_Testing_Jestjs - Fatal编程技术网

Javascript 具有异步函数的有状态React组件未能通过Jest测试

Javascript 具有异步函数的有状态React组件未能通过Jest测试,javascript,reactjs,unit-testing,testing,jestjs,Javascript,Reactjs,Unit Testing,Testing,Jestjs,在这件事上,我一直在跟进。我写的代码和作者完全一样,但由于某种原因,我的测试没有通过 我对作者回购的请求: 我有一个简单的React组件,它通过对componentDidMount中的服务的异步/等待调用来更新它的count状态 {this.state.count != -1 ? `${this.state.count} Notifications Awaiting` : 'Loading...'} 预期 由于我模拟了NotificationsService,并将count设置为42,因此测试

在这件事上,我一直在跟进。我写的代码和作者完全一样,但由于某种原因,我的测试没有通过

我对作者回购的请求:

我有一个简单的React组件,它通过对
componentDidMount
中的服务的异步/等待调用来更新它的
count
状态

{this.state.count != -1 ? `${this.state.count} Notifications Awaiting` : 'Loading...'}
预期 由于我模拟了NotificationsService,并将count设置为
42
,因此测试应该通过,组件中的文本为
“42个通知等待!”

结果 文本保持为默认的
加载…

我已经正确地模拟了服务,
count
变量甚至被正确地记录为
42
!但是,
this.state.count
仍然是
-1
,因此它不会显示等待
${this.state.count}通知,而是显示
加载…
,因此测试失败


我试过的 1) 我已经试着在延迟中增加1000

2) 尝试在测试中使用setTimeout

3) 尝试
jest.useFakeTimers()
jest.runAllTimers()

但是没有任何工作,组件内部的
计数
卡在
-1
上,即使
计数
设置为42。在我看来,我的测试是在状态设置完成之前运行的

NotificationsViewser.jsx组件 模拟:NotificationsService.js 最后

测试
从“React”导入React;
从“反应测试渲染器”导入渲染器;
“redux saga”的导入延迟;
从“../NotificationsViewer”导入NotificationsViewer;
jest.mock('../../services/NotificationsService');
const notificationService=require('../../services/NotificationsService')。默认值;
描述('通知查看器',()=>{
以前(()=>{
通知服务。设置计数(42);
});
它('应该显示正确的通知数',async()=>{
常量树=渲染器
.创造(
);
等待延迟();
const instance=tree.root;
const component=instance.findByProps({className:`notifications`});
const text=component.children[0];
log('文本为:',文本);
expect(text).toEqual('42个等待通知!');
});
})

也许您的
描述
也需要是一个异步函数
await
语句需要在
async
范围内声明,否?

问题在于
await delay()
无法让所有React生命周期方法(如
componentDidMount
实例化/调用)

我不得不使用
Enzyme
,尽管由于存在许多公开的bug问题,作者不推荐使用它

使用Enzyme,我可以确保调用
组件didmount
,从而使用模拟服务将
count
的状态设置为
42

我还需要安装以下软件包:

"enzyme": "^3.10.0",
"enzyme-adapter-react-16": "^1.14.0",
固定测试
从“React”导入React;
从“反应测试渲染器”导入渲染器;
从'enzyme-Adapter-react-16'导入适配器;
从“酶”导入{shallow,configure};
配置({adapter:newadapter()});
从“./NotificationsViewer”导入NotificationsViewer;
jest.mock(“../services/NotificationsService”);
const notificationService=require('../services/NotificationsService')。默认值;
notificationService.default=jest.fn();
描述('通知查看器',()=>{
以前(()=>{
通知服务。设置计数(42);
});
//它('pass',()=>{});
它('应该显示正确的通知数',async()=>{
常量树=renderer.create();
常量包装器=浅();
const instance=tree.root;
等待包装器.instance().componentDidMount();
const component=instance.findByProps({className:`notifications`});
const text=component.children[0];
log('文本为:',文本);
expect(text).toEqual(“等待42份通知”);
});
})

事实上,真正的问题在于
同构react/src/components/\uuuu tests\uuuu/NotificationsViewer.js
文件。
延迟
以错误的方式导入,导致测试错误


如果像这样导入
delay
import{delay}来自'redux saga'
修复问题=D

好的,所以我刚试过,但得到了这个警告>不支持从“描述”返回承诺。测试必须同步定义。在Jest.Ops的未来版本中,从“descripe”返回一个值将使测试失败,我错过了
it
块上的
async
。在我看来,
wait delay()
在测试
expect
块之前不允许先运行生命周期方法。因为
console.log的结果('text为:',text),然后命中
componentDidMount
componentDidUpdate
日志。这是正确的,我的导入错误。然而,将我下面的答案作为处理这个问题的首选方法,因为不是每个项目都会使用
redux saga
,我的示例解释了如何使用酶来解决这个问题:)
import { delay } from 'redux-saga';

export default {
  async GetNotifications() {
    console.warn("REAL NOTIFICATION SERVICE! CONTACTING APIS!");

    await delay(1000);
    return { count: 42 };
  }
}
let count = 0;

export default {
  __setCount(_count) {
    count = _count;
  },
  async GetNotifications() {
    console.warn("GOOD JOB! USING MOCK SERVICE");
    return { count };
  }
}
import React from 'react';
import renderer from 'react-test-renderer';
import delay from 'redux-saga';

import NotificationsViewer from '../NotificationsViewer';

jest.mock('../../services/NotificationsService');

const notificationService = require('../../services/NotificationsService').default;

describe('The notification viewer', () => {

  beforeAll(() => {
    notificationService.__setCount(42);
  });

  it('should display the correct number of notifications', async() => {
    const tree = renderer
      .create(
        <NotificationsViewer/>
      );

    await delay();

    const instance = tree.root;
    const component = instance.findByProps({className: `notifications`});
    const text = component.children[0];
    console.log('text is:', text);

    expect(text).toEqual('42 Notifications Awaiting!');
  });
})
"enzyme": "^3.10.0",
"enzyme-adapter-react-16": "^1.14.0",
import React from 'react';
import renderer from 'react-test-renderer';
import Adapter from 'enzyme-adapter-react-16';
import { shallow, configure } from 'enzyme';

configure({adapter: new Adapter()});

import NotificationsViewer from './NotificationsViewer';

jest.mock('../services/NotificationsService');

const notificationService = require('../services/NotificationsService').default;

notificationService.default = jest.fn();

describe('The notification viewer', () => {

  beforeAll(() => {
    notificationService.__setCount(42);
  });

  // it('pass', () => {});

  it('should display the correct number of notifications', async() => {
    const tree = renderer.create(<NotificationsViewer />);
    const wrapper = shallow(<NotificationsViewer />);
    const instance = tree.root;

    await wrapper.instance().componentDidMount();

    const component = instance.findByProps({className: `notifications`});
    const text = component.children[0];
    console.log('text is:', text);

    expect(text).toEqual('42 Notifications Awaiting');
  });
})