我正在try 使用jest.mock函数模拟@databricks/sql包,它不断地从 node 模块包中拉出,而不是我传递到该函数中的代码.

我的测试文件:

import mockResponse from "./mockResponse.json";

const {
  handler,
} = require("../../../backend/function/dataLakeConnect/src/index");

const testEvent = {
  arguments: {
    page: 1,
    clientId: "test",
    startTime: "2022-09-26 00:00:00",
    endTime: "2022-09-27 00:00:00",
  },
};

const exampleResponse = {
  ARN: "x",
  Name: "credentials/databricks/read-write",
  VersionId: "x",
  SecretString:
    '{"DATABRICKS_TOKEN":"test","DATABRICKS_SERVER_HOSTNAME":"test.test.com","DATABRICKS_HTTP_PATH":"/pathy/pathpath/mcgee"}',
  VersionStages: ["x"],
  CreatedDate: "x",
};

jest.mock("@databricks/sql", () => {
  return {
    DBSQLClient: function () {
      return {
        connect: function () {
          return {
            promise: function () {},
          };
        },
        openSession: function () {
          console.log("openSession called");
          return {
            promise: function () {
              return {
                executeStatement: function (sql, params) {
                  return {
                    promise: function () {
                      return {
                        fetchAll: function () {
                          return {
                            promise: function () {
                              return mockResponse;
                            },
                          };
                        },
                      };
                    },
                  };
                },
              };
            },
          };
        },
      };
    },
  };
});

jest.mock("aws-sdk", () => {
  return {
    SecretsManager: function () {
      return {
        getSecretValue: function ({ SecretId }) {
          if (SecretId === "credentials/databricks/read-write") {
            return {
              promise: function () {
                return exampleResponse;
              },
            };
          } else {
            throw new Error("mock error");
          }
        },
      };
    },
  };
});


describe("dataLakeConnect", () => {
  test("should return expected array", async () => {
    let res = await handler(testEvent);
    expect(res).toEqual(mockResponse);
  });
});

我正在try 测试的函数:

const AWS = require("aws-sdk");
const { DBSQLClient } = require("@databricks/sql");
const client = new AWS.SecretsManager({
  region: "us-east-1",
});
console.log(AWS);
console.log(DBSQLClient);
const databricksClient = new DBSQLClient();
const resultsPerPage = 300;

const getSecret = async (secretName) => {
  try {
    let data = await client.getSecretValue({ SecretId: secretName }).promise();
    if (data.SecretString) {
      return JSON.parse(data.SecretString);
    }
  } catch (err) {
    throw err;
  }
};

exports.handler = async (event) => {
  console.log(`EVENT: ${JSON.stringify(event)}`);
  const { page, clientId, startTime, endTime } = event.arguments;
  const offset = resultsPerPage * (page - 1);
  let sql = `SELECT * FROM test`;

  try {
    const creds = await getSecret("credentials/databricks/read-write");
    // console.log(databricksClient);
    await databricksClient.connect({
      token: creds.DATABRICKS_TOKEN,
      host: creds.DATABRICKS_SERVER_HOSTNAME,
      path: creds.DATABRICKS_HTTP_PATH,
    });
    const session = await databricksClient.openSession();
    const queryOperation = await session.executeStatement(sql, {
      runAsync: true,
      maxRows: 10000,
    });
    const result = await queryOperation.fetchAll({
      progress: false,
      callback: () => {},
    });

    await queryOperation.close();
    await session.close();
    await databricksClient.close();
    return result;
  } catch (err) {
    throw err;
  }
};

我期望此文件中的控制台日志(log)返回模拟代码,aws-sdk模拟似乎工作正常,然而,@databricks/sql控制台日志(log)返回原始模块,这会导致测试超时.

我试着像JEST建议的那样,将这些mock放在 node 模块旁边的__mocks__目录下,但最后出现错误,说Jest找不到包.

有没有什么建议可以让@databricks/sql模拟游戏真正发挥作用呢?我被难住了.

推荐答案

使用您的代码,模拟实际上(从问题中复制代码)可以工作,但我得到:

dataLakeConnect › should return expected array

    TypeError: session.executeStatement is not a function

      35 |     });
      36 |     const session = await databricksClient.openSession();
    > 37 |     const queryOperation = await session.executeStatement(sql, {
         |                                          ^
      38 |       runAsync: true,
      39 |       maxRows: 10000,
      40 |     });

将模拟更改为:

jest.mock("@databricks/sql", () => ({
  DBSQLClient: function () {
    return {
      connect: () => Promise.resolve({}),
      openSession: () => {
        console.log("openSession called");
        return Promise.resolve({
          executeStatement: () =>
            Promise.resolve({
              fetchAll: () => Promise.resolve(mockResponse),
              close: () => Promise.resolve({}),
            }),
          close: () => Promise.resolve({}),
        });
      },
      close: () => Promise.resolve({}),
    };
  },
}));

测试通过:

 ● Console

    console.log
      { SecretsManager: [Function: SecretsManager] }

      at Object.<anonymous> (src/totest.js:6:9)

    console.log
      [Function: DBSQLClient]

      at Object.<anonymous> (src/totest.js:7:9)

    console.log
      EVENT: {"arguments":{"page":1,"clientId":"test","startTime":"2022-09-26 00:00:00","endTime":"2022-09-27 00:00:00"}}

      at handler (src/totest.js:23:11)

    console.log
      openSession called

      at Object.openSession (src/__tests__/totest.spec.js:54:17)

Javascript相关问答推荐

使用axios.获取实时服务器时的404响应

如何解决CORS政策的问题

角色 map 集/spritebook动画,用户输入不停止在键上相位器3

如何粗体匹配的字母时输入搜索框使用javascript?

手机上的渲染错误文本必须在文本组件中渲染,但在浏览器上没有问题<><>

使用原型判断对象是否为类的实例

为什么我的getAsFile()方法返回空?

检索相加到点的子项

环境值在.js文件/Next.js中不起作用

如何在不影响隐式类型的情况下将类型分配给对象?

如何在JAVASCRIPT中合并两组对象并返回一些键

OpenAI转录API错误请求

搜索功能不是在分页的每一页上进行搜索

无法避免UV:flat的插值:非法使用保留字"

如何在和IF语句中使用||和&;&;?

背景动画让网站摇摇欲坠

输入的值的类型脚本array.排序()

如何根据查询结果重新排列日期

使用Java脚本筛选数组中最接近值最小的所有项

将数据添加到数据库时不输出