更新实现委托以进行更新,但不委托进行添加

时间:2020-04-27 04:05:58

标签: javascript node.js mongoose jestjs

我不习惯javascript或node.js。这是我第一次认真对待它,因为我的老板要求我这样做。 顺便说一句,这是我的代码:

//meta-dao.js
class MetaDAO {
    async getAll() {
        return await Meta.find().exec()
    }
    async getByCatalogId(catalogId) {
        return await Meta.find().where(catalogId).in('catalogs').exec()
    }
    async getById(id) {
        return await Meta.findOne({ id }).exec()
    }
    async add(meta) {
        return await (new Meta(meta)).save()
    }
    async update(meta) {
        return await Meta.update({ id: meta.id }, meta).exec()
    }
    async upsert(meta) {
        var exists = await this.getById(meta.id)
        console.log(exists)
        if(!exists){
            return await this.add(meta)
        }
        else {
            return await this.update(meta)
        }
    }
}
//meta-dao.test.js
it('Should insert when upsert a meta with new id', async () => {
    metaDAO.getById = jest.fn((id) => {
        return Promise.resolve(meta)
    })
    metaDAO.getById.bind(metaDAO)

    metaDAO.upsert(meta)

    expect(metaDAO.add).toBeCalledTimes(1)
    expect(metaDAO.add).toBeCalledWith(meta)
    expect(metaDAO.getById).toBeCalledTimes(1)
    expect(metaDAO.getById).toBeCalledWith(meta.id)
    expect(metaDAO.update).not.toBeCalled()
})
it('Should update when upsert a meta with known id', async () => {
    metaDAO.getById = jest.fn((id) => {
        return Promise.resolve(null)
    })
    metaDAO.getById.bind(metaDAO)

    metaDAO.upsert(meta)

    expect(metaDAO.update).toBeCalledTimes(1)
    expect(metaDAO.update).toBeCalledWith(meta)
    expect(metaDAO.getById).toBeCalledTimes(1)
    expect(metaDAO.getById).toBeCalledWith(meta.id)
    expect(metaDAO.add).not.toBeCalled()
})

第二个测试用例的所有断言都通过了。但是第一个测试用例中的expect(metaDAO.add).toBeCalledTimes(1)失败了。 console.log打印“ null”,我已经尝试使用:

  • if(exists == null)
  • if(exists === null)
  • if(exists == undefined)
  • if(exists === undefined)
  • if(exists)

似乎没有什么区别。行为是

  • 如果存在不为空则调用更新
  • 如果存在为空,则不会调用

我在做什么错?我想念什么吗?

1 个答案:

答案 0 :(得分:0)

我的嘲笑是不正确的。我应该使用jest.fn()fn.bind(object)来代替jest.spyOnspy.mockRestore()

以下代码已更正并可以正常工作!

//meta-dao.test.js
beforeAll(() => {
    metaDAO = new MetaDAO()
})
it('Should insert when upsert a meta with new id', async () => {
    const addSpy = jest.spyOn(metaDAO,"add").mockImplementation(()=>{})
    const updateSpy = jest.spyOn(metaDAO,"update").mockImplementation(()=>{})
    const getIdSpy = jest.spyOn(metaDAO,"getById").mockImplementation((id) => {
        return Promise.resolve(null)
    })
    metaDAO.getById.bind(metaDAO)

    await metaDAO.upsert(meta)

    expect(addSpy).toBeCalledTimes(1)
    expect(addSpy).toBeCalledWith(meta)
    expect(getIdSpy).toBeCalledTimes(1)
    expect(getIdSpy).toBeCalledWith(meta.id)
    expect(updateSpy).not.toBeCalled()

    addSpy.mockRestore()
    updateSpy.mockRestore()
    getIdSpy.mockRestore()
})
it('Should update when upsert a meta with known id', async () => {
    const addSpy = jest.spyOn(metaDAO,"add").mockImplementation(()=>{})
    const updateSpy = jest.spyOn(metaDAO,"update").mockImplementation(()=>{})
    const getIdSpy = jest.spyOn(metaDAO,"getById").mockImplementation((id) => {
        return Promise.resolve(meta)
    })
    metaDAO.getById.bind(metaDAO)

    await metaDAO.upsert(meta)

    expect(updateSpy).toBeCalledTimes(1)
    expect(updateSpy).toBeCalledWith(meta)
    expect(getIdSpy).toBeCalledTimes(1)
    expect(getIdSpy).toBeCalledWith(meta.id)
    expect(addSpy).not.toBeCalled()

    addSpy.mockRestore()
    updateSpy.mockRestore()
    getIdSpy.mockRestore()
})

另一方面,源代码已经可以了。