2017-09-26 10 views
2

私は最後の数日間rxjsとredux-observableで遊んでいて、Observable.ajaxのテストへの道を見つけるのが苦労しています。私は、ブラウザで実行されますが、冗談でテストしていないときときObservable.ajax(redux-observable)はどのようにテストできますか?

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 } 
} 

コードが正常に動作し、

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)) 
    ) 
} 

https://jsonplaceholder.typicode.com/にリクエストを作成するには、次の叙事詩を持っています。私が試してみる

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に基づいてテストを作成します。

タイムアウト - 非同期コールバックが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をテストするための正しい方法は何か私を指摘することはできますか?

答えて

2

私はStackOverflowの2番目の例に従います。それを機能させるには、少し調整する必要があります。あなたの叙事詩のファイルにObservable.ajaxをインポートする代わりに、その参照を直接使用する場合は、何らかの依存性注入を使用する必要があります。 1つの方法は、ミドルウェアを作成するときにミドルウェアに提供することです。

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

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

dependenciesはまた3番目の引数として、すべての叙事詩に

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(); 
     } 
    }); 
}); 
を与える必要があります です
関連する問題