Rx.Observable.fromPromise不使用Redux-Observable Epics

时间:2017-05-22 21:33:51

标签: javascript unit-testing redux reactive-programming redux-observable

我目前正在开发一个本机应用程序,并试图将redux-observable用于带有redux的中间件。

为简单起见,我只包含包含承诺的史诗,而不是用网络代码稀释它。

这是针对身份验证API的单元测试,该API仅使用用户名,密码,并应返回用户名,密码和身份验证令牌。同样,这应立即返回,并使商店包含AUTHENTICATEAUTHENTICATE_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'}))
        )

注意:我的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没有给出我期待的行为。我把它缩小到了承诺的问题。基本上这将是网络请求的结果,然后进行相应的处理。

感谢您的帮助。

0 个答案:

没有答案