2016-11-23 15 views
1

redux-sagaの使い方を教えていますが、同時にユニットテスト、特にJestを教えています。redux-saga-test-planでredux-saga関数をテストする方法を理解できません

http://yelouafi.github.io/redux-saga/docs/advanced/NonBlockingCalls.html

を...そして私自身の目的のためにそれを修正:私はここで、Reduxの-サガのドキュメントからサンプルサガを取りました。ユーザーがログインしているかどうかを関数が認識しないため、ログインまたはログアウトアクションのいずれかをリッスンしてから、適切な処置を実行する単純な認証ハンドラであると考えられます。私は、アプリケーション内の関数をテストし、それは素晴らしいと期待どおり機能するように見えます。関数は次のとおりです。

これはかなり簡単ですが、テストするのは苦労しています。私が間違っサガをやっている、または私はサガをテストする方法を理解していない、または佐賀のこの種をテストするので、どちらか

it ('authFlow() should work with successful login and then successful logout',() => { 
    const mockCredentials = {username: 'User', password: 'goodpassword'}; 
    testSaga(stateAuth.watcher) 
    //this should test the first 'yield', which is waiting for LOGIN or LOGOUT. It works 
    .next().take(['LOGIN', 'LOGOUT']) 

    // This should test 'authorizeWithRemoteServer', and appears to do that properly 
    .next({type: 'LOGIN', payload: mockCredentials}).fork(stateAuth.authorizeWithRemoteServer, mockCredentials) 

    // This should reflect 'yield take' after the 'yield fork', and does so 
    .next().take(['LOGOUT', 'LOGIN_FAIL']) 

    /* this is where I don't understand what's happening. What I would think I should do is something like this, if I want to test the logout path: 
    .next({type: 'LOGOUT'}).cancel(createMockTask()) 

    ...but that results in the following, perhaps predictable, error: 

    cancel(task): argument task is undefined 

    What I found does make the test not fail is the following line, but 
    I do not understand why it works. The fact that it matches 
    "take(['LOGIN', 'LOGOUT'])" indicates that it has 
    looped back to the top of the generator 
    */ 
    .next(createMockTask()).take(['LOGIN', 'LOGOUT']) 
}) 

本当にハードにされています。以下は、私の冗談ベースのテストスクリプトの注釈付きバージョンです。おそらく実用的ではありません。

ここで何が起こっているのですか?前もって感謝します!

答えて

3

答えはまだあなたに関連している場合は知っているが、ただ将来的には、この時にケースの他の誰つまずくではいけない:行で

.next().take(['LOGOUT', 'LOGIN_FAIL']) 

あなたは基本的にundefinedを渡していますこのライン上の収率ことを意味する:

const action = yield take(['LOGOUT', 'LOGIN_FAIL']); 

actionundefinedさせます。私は、これは正しいテスト

it ('authFlow() should work with successful login and then successful logout',() => { 
    const mockCredentials = {username: 'User', password: 'goodpassword'}; 
    testSaga(stateAuth.watcher) 
    //this should test the first 'yield', which is waiting for LOGIN or LOGOUT. It works 
    .next().take(['LOGIN', 'LOGOUT']) 

    // This should test 'authorizeWithRemoteServer', and appears to do that properly 
    .next({type: 'LOGIN', payload: mockCredentials}).fork(stateAuth.authorizeWithRemoteServer, mockCredentials) 

    // We pass a mock task here 
    .next(createMockTask()).take(['LOGOUT', 'LOGIN_FAIL']) 

    // And then this should be correct 
    .next({type: 'LOGOUT'}).cancel(createMockTask()) 

    // after which the saga loops back 
    .take(['LOGIN', 'LOGOUT']) 
}) 

next()を呼び出すときに、あなたが果たしていることを忘れないでくださいことだと思い

.next(createMockTask()).take(['LOGOUT', 'LOGIN_FAIL']) 

はあなたがやるべきことは、その行にモックタスクを渡しています前回の利回り。

更新:whoops、createMockTask()の結果は、アサートのために使用できるように格納する必要があります。これは正しいコードでなければなりません。

it ('authFlow() should work with successful login and then successful logout',() => { 
    const mockCredentials = {username: 'User', password: 'goodpassword'}; 
    const mockTask = createMockTask(); 
    testSaga(stateAuth.watcher) 
    //this should test the first 'yield', which is waiting for LOGIN or LOGOUT. It works 
    .next().take(['LOGIN', 'LOGOUT']) 

    // This should test 'authorizeWithRemoteServer', and appears to do that properly 
    .next({type: 'LOGIN', payload: mockCredentials}).fork(stateAuth.authorizeWithRemoteServer, mockCredentials) 

    // We pass a mock task here 
    .next(mockTask).take(['LOGOUT', 'LOGIN_FAIL']) 

    // And then this should be correct 
    .next({type: 'LOGOUT'}).cancel(mockTask) 

    // after which the saga loops back 
    .take(['LOGIN', 'LOGOUT']) 
}) 
+0

ありがとうございます!明日私が仕事に戻ったときに私はテストをします。 – hairbo

+0

アサーション4は失敗しました:私はあなたの提案を(感謝!)、試みたが、私に近づくが、今すぐ '.next({type:actions.LOGOUT})cancel(createMockTask())'キャンセル効果は一致しませんが、 "expected"と "actual"の値が一致します。私は、次回のコメントで実際のものと予想されるものの内容を投稿します。 – hairbo

+0

期待値: {'@@ redux-saga/TASK':true、isRunning:[関数:isRunning]、結果:[関数:結果]、エラー:[関数:エラー]、setRunning:[関数:setRunning]、setResult [機能:setResult]、setError:[機能:setError]} 実際: {'@@ redux-saga/TASK':true、isRunning:[機能:isRunning]、結果:[機能:結果]、エラー: [Function:error]、setRunning:[Function:setRunning]、setResult:[Function:setResult]、setError:[機能:setError]} – hairbo

関連する問題