测试耗时且来自运算符的史诗

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

我有这个史诗,需要测试的帮助,对异步方法的史诗调用(来自运算符),它使用了延迟运算符

export const getAll$ = (
  action$: any,
  state: { value: TStore },
  { stock, Error }: TDependencies
) => {
  return action$.pipe(
    ofType(getAll.toString()),
    map(({ meta: { failures} }) => ({
      failures,
    })),
    switchMap(({ failures }) => {
      return merge(
        of(getAllStart()),
        // call api service stock.getAll, this is async
        from(stock.getAll()).pipe(
          // wait a 1 second, not matter if stock.getAll finish early
          delay(OPERATION_DELAY),
          switchMap((response: TGetAllResponse) => {
            if(response instanceof Error) {
              return throwError(response);
            }
            return of(
              getAllSuccess()
            );
          }),
          catchError((error) => {
            return failures === 0 ?
              of(getAllFailure({ error }))
              :
              of(getAll({
                failures: failures + 1,
              })).pipe(
                delay(FAILURE_RETRY_TIME),
              );
          }),
          // "cancel" this epic if getAllAbort action is emitted
          takeUntil(
            action$.ofType(
              getAllAbort.toString()
            )
          )
        )
      )
    })
  )
};

这是我的考试


import { ActionsObservable } from 'redux-observable';

// some mocking

const state = { value: {} };

const dependencies = {
  api: {},
  stock: {
    getAll() {
      return [];
    }
  },
  Error: class Error {},
};

describe('stock epic', () => {
  it('should return all products', (done) => {
    // start epic getAll$
    getAll$(ActionsObservable.of(getAll()), state, dependencies).subscribe((action) => {
      console.log(action); //  { type: 'STOCK/GET_ALL_START' }
      done();
    });
  });
});

如果看到console.log(action);仅返回{ type: 'STOCK/GET_ALL_START' }如果我使用.toArray(),则测试永无止境

我正在发布lorem impsun,因为堆栈溢出抱怨我的问题

Lorem ipsum dolor atmet,奉献自若。 Proin ac blandit leo。菜豆未播种或未播种。菜豆非feugiat lorem,neultricies quam。在porttitor bibendum facilisis。 Donec euismod imperdiet tincidunt。 Mauris enim ante,susculit iaculis mi et,convallis fermentum ante。 Vestibulum eget purus pharetra,finibus velit,porta metus。 Vivamus interdum lobortis elit,dignissim tempor sem。 Nam礼仪,舒张期舒张期,尼古拉·伊库图斯·托马斯·托,非索利丁定居者。 Nam vel lacus feugiat lorem venenatis interdum。

redux-observable
1个回答
0
投票

[几个小时后,我找到了解决方案,如果您的史诗使用from运算符,则无法对其进行测试,则需要模拟该运算符,就我而言,我只是将此运算符映射为of运算符很容易,在您的根项目文件夹中创建一个名为__mocks__的文件夹,并在其中创建一个名为rxjs.js的js文件,然后将此代码放入其中]

const rxjs = jest.requireActual('rxjs');
rxjs.from = rxjs.of;
module.exports = rxjs;

然后用于测试您是否需要使用类TestScheduler,它在rxjs/testing中可以作为导出常量使用

代码会这样

import { ActionsObservable } from 'redux-observable';
import { TestScheduler } from 'rxjs/testing';

// your epics to be tested
import epics from './stock';

// actions that you epic will emit
import {
  getAll,
  getAllStart,
  getAllSuccess,
} from '../actions/stock';

// mock the state param (if your epic use it)
import { initialState } from '../reducers/stock';

const state = {
  value: {
    stock: initialState,
  },
};

// mock your dependencies param
const dependencies = {
  api: {},
  stock: {
    getAll() { // in my real code, this is a promise, here is just a normal function, perfect to be use with the of operator
      return [];
    },
  },
  Error: class Error {},
};

describe('stock epic', () => {

  it('should return all products', (done) => {

    // this is just copy-paste
    const testScheduler = new TestScheduler((actual, expected) => {
      expect(actual).toStrictEqual(expected);
    });

    testScheduler.run(({ cold, hot, expectObservable, expectSubscriptions, flush }) => {
      expectObservable(
        epics.getAll$(
          ActionsObservable.of(getAll()), // transform action to action$
          state, // pass mocked state
          dependencies // pass mocked dependencies
        )
      ).toBe(
        // my epic has a delay(1000) call
        'a 999ms (b|)', {
          a: getAllStart(),
          b: getAllSuccess()
        }
      );
      done();
    });
  });

});
© www.soinside.com 2019 - 2024. All rights reserved.