私は現在、反応するネイティブアプリに取り組んでおり、 redux を使用したミドルウェアにredux-observableを使用しようとしています。
簡単にするために、promise を含むエピックのみを含め、ネットワーク コードで希釈しません。
これは、ユーザー名、パスワードのみを受け取り、ユーザー名、パスワード、および認証トークンを返す必要がある認証 API に対する私の単体テストです。繰り返しますが、これは即座に返され、ストアに含まれている必要がありますAUTHENTICATE
。AUTHENTICATE_FULFILLED
import configureMockStore from 'redux-mock-store';
import { createEpicMiddleware } from 'redux-observable';
import * as servicesRoot from '../app/services/root'
const epicMiddleware = createEpicMiddleware(servicesRoot.epics);
const mockStore = configureMockStore([epicMiddleware]);
describe('Session Service', () => {
let store;
beforeEach(() => {
store = mockStore();
});
afterEach(() => {
epicMiddleware.replaceEpic(servicesRoot.epics)
});
describe('Authentication API', () => {
it('I should receive an authToken', () => {
let username = 'myUsername'
let password = 'myPassword'
const data = { username, password, authToken: 'test_auth_token' };
let action = servicesRoot.actions.authenticate(username, password)
store.dispatch(action)
expect(store.getActions()).toEqual([
servicesRoot.actions.authenticate(username, password),
servicesRoot.actions.authenticate_fulfilled(data)
]);
})
})
})
私の認証叙事詩は次のようになります
import Rx from 'rxjs'
import * as actionTypes from './actionTypes'
import { authenticate_fulfilled } from './actions'
export const authenticateEpic = action$ =>
action$.ofType(actionTypes.AUTHENTICATE)
.mergeMap(action =>
Rx.Observable.fromPromise(Promise.resolve('test'))
.map(result => authenticate_fulfilled({ ...action.payload, authToken: 'test_auth_token'}))
)
注: myは、タイプservicesRoot.actions.authenticate
を含む使用するアクションを返し、別のアクションを返します。AUTHENTICATE
authenticate_fulfilled
AUTHENTICATE_FULFILLED
単体テストからの私の出力は
FAIL __tests__/api.js
● Session Service › Authentication API › I should receive an authToken
expect(received).toEqual(expected)
Expected value to equal:
[{"payload": {"password": "myPassword", "username": "myUsername"}, "type": "AUTHENTICATE"}, {"payload": {"authToken": "test_auth_token", "password": "myPassword", "username": "myUsername"}, "type": "AUTHENTICATE_FULFILLED"}]
Received:
[{"payload": {"password": "myPassword", "username": "myUsername"}, "type": "AUTHENTICATE"}]
Difference:
- Expected
+ Received
@@ -4,14 +4,6 @@
"password": "myPassword",
"username": "myUsername",
},
"type": "AUTHENTICATE",
},
- Object {
- "payload": Object {
- "authToken": "test_auth_token",
- "password": "myPassword",
- "username": "myUsername",
- },
- "type": "AUTHENTICATE_FULFILLED",
- },
]
at Object.<anonymous> (__tests__/api.js:36:28)
Session Service
Authentication API
✕ I should receive an authToken (44ms)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: 1.15s
Ran all test suites matching /api/.
エピックを次のように変更すると、テストに合格します
export const authenticateEpic = action$ =>
action$.ofType(actionTypes.AUTHENTICATE)
.mergeMap(action =>
Rx.Observable.of('test')
.map(result => authenticate_fulfilled({ ...action.payload, authToken: 'test_auth_token'}))
)
fromPromise
が期待どおりの動作をしない理由がわかりません。私はそれを約束の問題に絞り込みました。基本的に、これはネットワーク リクエストの結果であり、それに応じて処理されます。
助けてくれてありがとう。