如何在 fastify 注入中使用 node-tap 模拟函数

How to mock function using node-tap on fastify inject

我想用 node-tap 对此函数进行 100% 覆盖,但我无法模拟错误部分,它总是抛出

Cannot find module 'create' Require stack: - /home/mptr8/Code/Projects/me/fastify-example/fastify-postgres/test/integration.js

但是我的 query.js 文件中有 create 函数,我做错了什么?为什么它不调用该方法?

    t.mock("../query.js", {
      create: () => {
        throw new Error();
      },
    });

我也试试这个组合,因为query.js依赖于db.js。现在模拟错误消失了,但我仍然没有从 fastify.inject.

中得到错误抛出
    t.mock("../db.js", {
      "../query.js": {
        create: () => { throw new Error() },
      },
    });

     app.post("/", async (request, reply) => {
    try {
      const { body } = request;
      const book = create(body.title);
      reply.send(book);
    } catch (error) {
      // this part are not covered
      reply.code(500).send({ message: "internal server error" });
    }
  });


这是我的完整代码。您可以在 github repository.

上查看完整代码
// server.js

const fastify = require("fastify");

const {
  migration,
  create,
} = require("./query");

const db = require("./db");

function build(opts = {}) {
  const app = fastify(opts);

  migration();

  app.post("/", async (request, reply) => {
    try {
      const { body } = request;
      const book = create(body.title);
      reply.send(book);
    } catch (error) {
      reply.code(500).send({ message: "internal server error" });
    }
  });

  app.addHook("onClose", (_instance, done) => {
    db.close();
    done();
  });
}

module.exports = build;
// db.js
const { Pool } = require("pg");
const pool = new Pool({
  connectionString:
    "postgresql://postgres:postgres@localhost:5432/fastify_postgres?schema=public",
});

module.exports = {
  query: (text, params) => pool.query(text, params),
  close: () => pool.end(),
};
// query.js
const db = require("./db");

async function migration() {
  await db.query(`
    CREATE TABLE IF NOT EXISTS books (
      id serial PRIMARY KEY,
      title varchar (255) NOT NULL
    )
  `);
}

async function create(title) {
  return await db.query("INSERT INTO books (title) VALUES ()", [title]);
}

module.exports = { migration, create };
// test.js
const tap = require("tap");
const fastify = require("../server");

tap.test("coba", async (t) => {
  const app = await fastify();
  t.test("should success create books", async (t) => {
    const response = await app.inject({
      method: "POST",
      url: "/",
      payload: {
        title: "Hello,World!",
      },
    });
    t.equal(response.statusCode, 200);
  });

  t.test("should throw error", async (t) => {
    const app = await fastify();
    // it doesn't throw the error :((
    t.mock("../query.js", {
      create: () => {
        throw new Error();
      },
    });
    const response = await app.inject({
      method: "POST",
      url: "/",
      payload: {
        title: "Hello,World!",
      },
    });
    t.equal(response.statusCode, 500);
    // call app close on last test child to close app and db properly
    app.close();
  });
});

您应该使用 t.mock 函数的返回值:

const build = t.mock({ 
  "../server": {
    "./query.js": {
      create: () => { throw new Error() },
    }
  }
})
const app = await build({})