反应模拟 Graphql 订阅

React mock Graphql subscription

我有一个 React 项目,我正在使用 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 is not a function

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

您需要将 API.graphql 的 return 值模拟为来自反应式编程的 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  Whosebug/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