如何在redux saga中使用jest测试嵌套的firestore批量函数?

问题描述 投票:0回答:1

在一个react项目中,我有一个redux-saga文件,我在firebase后台(firestore)创建并保存新的项目。

在那个saga函数中,我是先得到一个新的写批处理对象,然后更新firestore文件,最后提交批处理。

传奇工作者

import { call, put } from 'redux-saga/effects'
import { db } from './firebase' // db: firebase.firestore()

export function* mySaga(item) {
    try {
        // init firestore batch.
        const batch = yield call(db, db.batch)

        // Set firestore document and save new item.
        const itemRef = yield call ([db, db.doc], `/items/${item.id}`)
        yield call([batch, batch.set], itemRef , item)

        // Commit the batch.
        yield call([batch, batch.commit])


        yield put({type: 'success'})
    } catch (err) {
        yield put({type: 'error', payload: err})
    }
}

传奇手游测试

import * as sagas from './mySaga'

describe('mySaga', () => {
    const spyOnDoc = jest.spyOn(db, 'doc')

    it('handles item creation', async () => {

        const dispatched = []
        await runSaga(
            { dispatch: action => dispatched.push(action) },
            sagas.mySaga,
        ).toPromise()

        expect(spyOnDoc).toHaveBeenCalledTimes(1)

        // !!! Here I need to check for nested set and commit functions of the batch object created in saga.

    })
})

如何测试批处理函数的嵌套 "set "和 "commit "函数,检查它们是否被调用了x次,并且调用的输入是否正确?

如果有任何帮助,我将感激不尽。

firebase testing google-cloud-firestore jestjs redux-saga
1个回答
0
投票

经过几次尝试,我想出了一个方法来完成这种测试。如果有人需要这个解决方案,这里是。

db.batch() 方法创建一个 firebase.firestore.WriteBatch 对象。而这个对象有 commit, set, updatedelete 方法。更多细节可参见 此处.

终极传奇》手游测试

import * as sagas from './mySaga'
import { db } from './firebase' // db: firebase.firestore()

describe('mySaga', () => {
    const spyOnDoc = jest.spyOn(db, 'doc')

    // We are mocking the methods of this predefined object.
    firestore.WriteBatch.set = jest.fn()
    firestore.WriteBatch.commit = jest.fn()

    // Then we implement those created mocks into the batch's mock implementation.
    const spyOnBatch = jest.spyOn(db, 'batch').mockImplementation(() => ({
        set: firestore.WriteBatch.set,
        commit: firestore.WriteBatch.commit,
    }))

    it('handles item creation', async () => {

        const dispatched = []
        await runSaga(
            { dispatch: action => dispatched.push(action) },
            sagas.mySaga,
            {id: 123} // Item
        ).toPromise()

        expect(spyOnDoc).toHaveBeenCalledTimes(1)

        // Finally, we can test those nested object functions as below.
        expect(firestore.WriteBatch.commit).toHaveBeenCalledTimes(1)
        expect(firestore.WriteBatch.set).toHaveBeenCalledTimes(1)
        expect(firestore.WriteBatch.set).toHaveBeenCalledWith(db.doc('/items/123'), {id: 123})

    })
})

© www.soinside.com 2019 - 2024. All rights reserved.