4

Redux の Writing Tests セクション ( http://rackt.org/redux/docs/recipes/WritingTests.htmlstore.dispatch(actions.fetchTodos()) ) で、store.dispatch が文字通り actions.fetchTodos を呼び出している場合、どのようにして fetch メソッドを呼び出さないのでしょうか?

it('creates FETCH_TODOS_SUCCESS when fetching todos has been done', (done) => {
    nock('http://example.com/')
      .get('/todos')
      .reply(200, { todos: ['do something'] })

const expectedActions = [
  { type: types.FETCH_TODOS_REQUEST },
  { type: types.FETCH_TODOS_SUCCESS, body: { todos: ['do something']  } }
]
const store = mockStore({ todos: [] }, expectedActions, done)
store.dispatch(actions.fetchTodos())


})

これに似たものを実行しようとするたびに、フェッチが定義されていません。ノックを使っても。したがって、フェッチの呼び出しを受け取らないように、自分のアクションをスパイする必要があります。

これが私の単体テストです:

it('should request a password reset, and then return success on 200', (done) => {
        nock('http://localhost:8080/')
        .post('/password-reset-requests')
        .reply(200);


var email = "test@email.com";
        const expectedActions=[
            {type: REQUEST_ADD_PASSWORD_RESET_REQUEST},
            {type: REQUEST_ADD_PASSWORD_RESET_REQUEST_SUCCESS}
        ];
        const store = mockStore({}, expectedActions, done);
        store.dispatch(Actions.addPasswordResetRequest());

アクションは次のとおりです。

export default function addPasswordResetRequest(email){
    return dispatch => {
        dispatch(requestAddPasswordResetRequest(email));
        return addPasswordResetRequestAPI(email)
            .then(() =>{
                dispatch(requestAddPasswordResetRequestSuccess());
            })
            .catch((error) => {
            dispatch(requestAddPasswordResetRequestFailure(error));
        });
    };
}

および fetch を呼び出す関数:

export const addPasswordResetRequestAPI = (email) => {
    return fetch(
        SETTINGS.API_ROOT + '/password-reset-requests',
        {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                email: email,
                code: NC_SETTINGS.GROUP.code
            })
        }
    )
        .then(handleResponse);
};

私がやっている方法がアクションをテストするだけの目的で十分かどうかはわかりませんが、store.dispatch が expectedActions の最初の要素のみを返すという問題に遭遇し、リストと等しくありませんスパイされた addPasswordResetRequest で提供します。以下は、スパイされたアクションを含みます。

it('should request a password reset, and then return success on 200', (done) => {
        nock('http://localhost:8080/')
        .post('/password-reset-requests')
        .reply(200);
        Actions.addPasswordResetRequest = spy(() => {
    return ([
            {type: REQUEST_ADD_PASSWORD_RESET_REQUEST},
            {type: REQUEST_ADD_PASSWORD_RESET_REQUEST_SUCCESS}
        ]
        );
});
        var email = "test@email.com";
        const expectedActions=[
            {type: REQUEST_ADD_PASSWORD_RESET_REQUEST},
            {type: REQUEST_ADD_PASSWORD_RESET_REQUEST_SUCCESS}
        ];

        const store = mockStore({}, expectedActions, done);
        store.dispatch(Actions.addPasswordResetRequest());
4

1 に答える 1

2

アクション「addPasswordResetRequest」は、言うまでもなくアクションではありません。

3 つのサブアクションを持つ複合アクションです。

startAction   =requestAddPasswordResetRequest,
successAction =requestAddPasswordResetRequestSuccess 
failAction    =requestAddPasswordResetRequestFailure

通常、各アクションを個別にテストします。だから私は次のようなものを持っているでしょう

describe("requestAddPasswordResetRequest", () => {
     it("shows the loading spinner or whatever", ...);
     it("does some other state change maybe", ...);
});
describe("requestAddPasswordResetRequestSuccess", () => {
     it("hides the loading spinner or whatever", ...);
     it("changes the password state or something", ...);
});
describe("requestAddPasswordResetRequestFailure", () => {
     it("hides the loading spinner or whatever", ...);
     it("shows the error somehow", ...);
});

//each test would be something like
it("changes the password state or something", ()=>{
    const action = requestAddPasswordResetRequestSuccess({
          some : "payload from the server"
    });
    const newState = myReducer({ state : "somestate" }, action);
    expect(newState).to.be.eql("expected result for that action"); 
});

テストでは、ストアや非同期ロジックが必要ないことに注意してください。それがreduxの美しさです(そして一般的に機能的なもの)、それは簡単です:)

この後、全体に対して個別のテストを行い、正しい単純なアクションが複合アクションによってディスパッチされることを確認します。その中で、すべてをモックします (ストアと「フェッチ」を含む、それをテストしたいだけなので)。アクションは正しい順序で起動されます)。

アクションが正しい順序でディスパッチされ、各アクションが別々に機能する場合、期待どおりに機能すると確信できます。

お役に立てれば。

于 2016-01-13T08:57:08.273 に答える