【问题标题】:How to test a NodeJS controller with a nested dependency?如何测试具有嵌套依赖项的 NodeJS 控制器?
【发布时间】:2020-05-25 17:14:54
【问题描述】:

我有一个从文件加载JSON 的服务:

import { promises, existsSync } from "fs";

import { dataPath } from "../../utils";

export const getUsersService = async () => {
  if (!existsSync(dataPath)) {
    console.log("File not found");
  }

  const data = await promises.readFile(dataPath, "utf8");
  return data;
};

然后我有一个控制器,它将成为Express 路由器的处理程序:

export const getUsers = async (
  req: Request,
  res: Response,
  next: NextFunction
) => {
  try {
    const result = await getUsersService();
    const users = JSON.parse(result);

    if (!users) throw new Error("There are no users");

    res.status(200).send(users);
  } catch (err) {
    next(err);
  }
};

这个控制器的使用如下:

const router = express.Router();

router.get("/", getUsers);

在我的测试文件中:

import { getUsersService } from "../../../../services/users";

// I mock the service since it's not what I want to test but I want to control what gets returned

jest.mock("../../../../services/users");

const mockGetUsersService = getUsersService as jest.Mock;

describe("getUsersController", () => {

  beforeEach(() => {
    jest.clearAllMocks();
  });

  it("responds with a 404 if there is no user", async () => {
    const req = {body: {}, params: {}}
    const res = {
      send: jest.fn(() => res)
      message: jest.fn(() => res)
      status: jest.fn(() => res)
      json: jest.fn(() => res)
  };
    const next = jest.fn();

    mockGetUsersService.mockResolvedValueOnce('fake user');
    const result = await getUsers(req, res, next);

    expect(mockGetUsersService).toBeCalled(); 
      // PASSED

    expect(mockGetUsersService).toHaveBeenCalledWith(null); 
      // FAILED  
      // Expected: null
      // Received: called with 0 arguments

    expect(res.status).toBe(404);
      // FAILED
      // Expected: 404
      //Received: [Function mockConstructor]
  });
});

我还想测试它是否收到 200,以防它返回数据,但我需要先弄清楚我的方法有什么问题。

谢谢

【问题讨论】:

  • 你在哪里可以解决这个问题?

标签: node.js typescript unit-testing express jestjs


【解决方案1】:

你想使用supertesthttps://www.npmjs.com/package/supertest

不要模拟 Request 或 Response 对象。只需使用超测。

注意:您甚至不需要启动 express 服务器,只需将其传递给 supertest 实例即可。

【讨论】:

  • 我将使用 supertest 进行集成测试,但考虑更多的是单元测试
  • 对于单元测试,控制器超测试也可以工作,但您需要将控制器设置为 Express 路由器。 IE。在单元测试中,创建一个express实例和use根路由上的控制器。现在利用 supertest 请求路径 '/' 以便执行控制器。利润。恕我直言,您应该避免模拟 Request 或 Responds 对象。
猜你喜欢
  • 2011-06-03
  • 2016-07-24
  • 1970-01-01
  • 2014-08-01
  • 2020-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多