React 模拟 Graphql 订阅

Posted

技术标签:

【中文标题】React 模拟 Graphql 订阅【英文标题】:React mock Graphql subscription 【发布时间】:2020-08-10 18:05:25 【问题描述】:

我有一个反应项目,我正在使用 Jest 进行测试。我正在尝试模拟对 AWS graphql 的调用,尤其是对订阅的调用。这是我要模拟的代码

await API.graphql(
    graphqlOperation(subscriptions.addedProduct))
    .subscribe(
      next: (response) => 
        this.setState( products: [...this.state.products, response.value.data.addedProduct] )
      
    );

我通常用 spyOn 模拟这样的东西......

const mockProducts = jest.spyOn(API, 'graphql').mockImplementation(async () =>
  Promise.resolve(mockResponse)
);

但会报错

TypeError: _awsAmplify.API.graphql(...).subscribe 不是函数

有没有人以类似方式模拟订阅的示例?

【问题讨论】:

【参考方案1】:

您需要将API.graphql 的返回值模拟为来自反应式编程的Observable。然后,您可以使用.subscribe 方法。下面的例子,我使用rxjsof操作符来创建一个Observable

例如

main.jsx:

import React,  Component  from 'react';
import  API  from './api';

export class MyComponent extends Component 
  constructor(props) 
    super(props);
    this.state = 
      products: [],
    ;
  
  async componentDidMount() 
    await API.graphql('graphqlOperation(subscriptions.addedProduct)').subscribe(
      next: (response) => 
        this.setState( products: [...this.state.products, response.value.data.addedProduct] );
      ,
    );
  

  render() 
    return <div>my component</div>;
  

main.test.js:

import  MyComponent  from './main';
import  API  from './api';
import  of  from 'rxjs';

describe('61454572', () => 
  it('should pass', async () => 
    const mockResponse =  value:  data:  addedProduct: 'fake product'   ;
    const graphqlSpy = jest.spyOn(API, 'graphql').mockImplementation(() => 
      return of(mockResponse);
    );
    const wrapper = shallow(<MyComponent></MyComponent>);
    expect(wrapper.state('products')).toEqual(['fake product']);
    expect(graphqlSpy).toBeCalledWith('graphqlOperation(subscriptions.addedProduct)');
    graphqlSpy.mockRestore();
  );
);

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

 PASS  ***/61454572/main.test.jsx (11.328s)
  61454572
    ✓ should pass (12ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |   88.24 |      100 |   83.33 |   86.67 |                   
 api.js   |      50 |      100 |       0 |      50 | 5-6               
 main.jsx |     100 |      100 |     100 |     100 |                   
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        13.119s

【讨论】:

以上是关于React 模拟 Graphql 订阅的主要内容,如果未能解决你的问题,请参考以下文章

我们如何从 GraphQL 的 RequestContextHolder 获取 GraphQL 的 HttpServletRequest(DefaultGlobalContext)(使用 graphq

使用 Express-GraphQL 和 React-Apollo 订阅 GraphQL

无法使用 graphq-request 表示嵌套对象输入类型的数组

使用带有 React 和 Apollo 的 graphql 订阅制作实时应用程序

用于删除和更新的 React GraphQL 订阅

我如何在 react-native 聊天应用程序中使用 GraphQl 订阅从 GraphQl 查询中获取实时更新