1

我想知道如何用 Jest 正确测试 Azure Functions。我已经阅读了 MSoft 提供的在线文档,但它非常模糊和简短。还有一些我发现的过时的文章并没有真正解释太多。这是我的理解:我理解如何用 Jest 测试普通的 JS 异步函数。而且我了解如何测试非常简单的 Azure Functions。但是,我不确定如何正确测试进行多个 API 调用等的更复杂的 Azure 函数。

例如,我有一个 HTTP 函数,它应该进行一些 API 调用并改变数据,然后返回输出。如何在测试中正确模拟 API 调用?该函数只有一个入口点。(意味着一个被导出的函数module.exports = async function(context,req)。所以我们所有的测试都通过那里进入。如果我有子函数进行调用,我无法从测试中访问它们。那么有没有一些巧妙的方法来模拟 API 调用?(因为实际调用测试期间的 API 是不好的做法/设计)

这是一个代码示例来说明我的意思

module.exports = async function (context, req)
{
    let response = {}

    if (req.body && req.body.id)
    {
        try
        {
            //get order details
            response = await getOrder(context, req)
        }
        catch (err)
        {
            response = await catchError(context, err);
        }
    }
    else
    {
        response.status = 400
        response.message = 'Missing Payload'
    }

    //respond
    context.res =
    {
        headers: { 'Content-Type': 'application/json' },
        status: response.status,
        body: response
    }
};

async function getOrder(context, req)
{
   //connection to db
   let db = await getDb() // <- how to mock this 

   //retrieve resource
   let item = await db.get...(id:req.body.id)... // <- and this

   //return 
   return {'status':200, 'data':item}
}


4

1 回答 1

0

考虑这个(简化的)示例。

src/index.js(Azure 函数入口点):

const { getInstance } = require('./db')

module.exports = async function (context) {
  // assuming we want to mock getInstance and db.getOrder
  const db = await getInstance()
  const order = await db.getOrder()

  return order
}

src/db.js

let db

async function getInstance() {
  if (db === undefined) {
    // connect ...
    db = new Database()
  }

  return db
}

class Database {
  async getOrder() {
    return 'result from real call'
  }
}

module.exports = {
  getInstance,
  Database,
}

src/__tests__/index.test.js

const handler = require('../index')
const db = require('../db')

jest.mock('../db')

describe('azure function handler', () => {
  it('should call mocked getOrder', async () => {
    const dbInstanceMock = new db.Database() // db.Database is already auto-mocked
    dbInstanceMock.getOrder.mockResolvedValue('result from mock call')

    db.getInstance.mockResolvedValue(dbInstanceMock)

    const fakeAzureContext = {} // fake the context accordingly so that it triggers "getOrder" in the handler
    const res = await handler(fakeAzureContext)

    expect(db.getInstance).toHaveBeenCalledTimes(1)
    expect(dbInstanceMock.getOrder).toHaveBeenCalledTimes(1)
    expect(res).toEqual('result from mock call')
  })
})
> jest --runInBand --verbose

 PASS  src/__tests__/index.test.js
  azure function handler
    ✓ should call mocked getOrder (4 ms)

如需完整的快速入门,您可能需要查看我的博客文章

于 2020-11-18T21:19:22.927 回答