gpt4 book ai didi

rxjs5 - 如何测试 Observable.ajax (redux-observable)?

转载 作者:行者123 更新时间:2023-12-04 23:38:39 24 4
gpt4 key购买 nike

在过去的几天里,我一直在使用 rxjs 和 redux-observable,并且一直在努力寻找一种方法来测试 Observable.ajax。我有以下史诗创建请求 https://jsonplaceholder.typicode.com/ ,

export function testApiEpic (action$) {
return action$.ofType(REQUEST)
.switchMap(action =>
Observable.ajax({ url, method })
.map(data => successTestApi(data.response))
.catch(error => failureTestApi(error))
.takeUntil(action$.ofType(CLEAR))
)
}

在哪里,
export const REQUEST = 'my-app/testApi/REQUEST'
export const SUCCESS = 'my-app/testApi/SUCCESS'
export const FAILURE = 'my-app/testApi/FAILURE'
export const CLEAR = 'my-app/testApi/CLEAR'

export function requestTestApi () {
return { type: REQUEST }
}
export function successTestApi (response) {
return { type: SUCCESS, response }
}
export function failureTestApi (error) {
return { type: FAILURE, error }
}
export function clearTestApi () {
return { type: CLEAR }
}

该代码在浏览器中运行时运行良好,但在使用 Jest 进行测试时运行良好。

我有尝试,

1) 基于 https://redux-observable.js.org/docs/recipes/WritingTests.html创建测试. store.getActions() 仅返回 { type: REQUEST }。
const epicMiddleware = createEpicMiddleware(testApiEpic)
const mockStore = configureMockStore([epicMiddleware])

describe.only('fetchUserEpic', () => {
let store

beforeEach(() => {
store = mockStore()
})

afterEach(() => {
epicMiddleware.replaceEpic(testApiEpic)
})

it('returns a response, () => {
store.dispatch({ type: REQUEST })
expect(store.getActions()).toEqual([
{ type: REQUEST },
{ type: SUCCESS, response }
])
})
})

2) 基于 Redux-observable: failed jest test for epic创建测试.它返回

Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.


  it('returns a response', (done) => {
const action$ = ActionsObservable.of({ type: REQUEST })
const store = { getState: () => {} }
testApiEpic(action$, store)
.toArray()
.subscribe(actions => {
expect(actions).to.deep.equal([
{ type: SUCCESS, response }
])
done()
})
})

有人可以指出测试 Observable.ajax 的正确方法是什么吗?

最佳答案

我将遵循 StackOverflow 中的第二个示例。为了让它工作,你需要做一些小的调整。而不是导入 Observable.ajax在您的史诗文件中并直接使用该引用,您需要使用某种形式的依赖注入(inject)。一种方法是在创建中间件时将其提供给中间件。

import { ajax } from 'rxjs/observable/dom/ajax';

const epicMiddleware = createEpicMiddleware(rootEpic, {
dependencies: { ajax }
});

我们作为 dependencies 传递的对象将作为第三个参数提供给所有史诗
export function testApiEpic (action$, store, { ajax }) {
return action$.ofType(REQUEST)
.switchMap(action =>
ajax({ url, method })
.map(data => successTestApi(data.response))
.catch(error => failureTestApi(error))
.takeUntil(action$.ofType(CLEAR))
);
}

或者,您不能使用 dependencies中间件的选项,而不是只使用默认参数:
export function testApiEpic (action$, store, ajax = Observable.ajax) {
return action$.ofType(REQUEST)
.switchMap(action =>
ajax({ url, method })
.map(data => successTestApi(data.response))
.catch(error => failureTestApi(error))
.takeUntil(action$.ofType(CLEAR))
);
}

无论您选择哪一个,当我们测试史诗时,我们现在都可以直接调用它并为其提供我们自己的模拟。以下是成功/错误/取消路径的示例 这些是未经测试的,可能有问题,但应该给你一个大致的想法
it('handles success path', (done) => {
const action$ = ActionsObservable.of(requestTestApi())
const store = null; // not used by epic
const dependencies = {
ajax: (url, method) => Observable.of({ url, method })
};

testApiEpic(action$, store, dependencies)
.toArray()
.subscribe(actions => {
expect(actions).to.deep.equal([
successTestApi({ url: '/whatever-it-is', method: 'WHATEVERITIS' })
])

done();
});
});

it('handles error path', (done) => {
const action$ = ActionsObservable.of(requestTestApi())
const store = null; // not used by epic
const dependencies = {
ajax: (url, method) => Observable.throw({ url, method })
};

testApiEpic(action$, store, dependencies)
.toArray()
.subscribe(actions => {
expect(actions).to.deep.equal([
failureTestApi({ url: '/whatever-it-is', method: 'WHATEVERITIS' })
])

done();
});
});

it('supports cancellation', (done) => {
const action$ = ActionsObservable.of(requestTestApi(), clearTestApi())
const store = null; // not used by epic
const dependencies = {
ajax: (url, method) => Observable.of({ url, method }).delay(100)
};
const onNext = chai.spy();

testApiEpic(action$, store, dependencies)
.toArray()
.subscribe({
next: onNext,
complete: () => {
onNext.should.not.have.been.called();
done();
}
});
});

关于rxjs5 - 如何测试 Observable.ajax (redux-observable)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46420952/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com