【问题标题】:Unit testing Express endpoint with express-session使用 express-session 对 Express 端点进行单元测试
【发布时间】:2021-01-05 01:20:15
【问题描述】:

我最近尝试为我的基本 CRUD REST API 编写一些单元测试。不幸的是,在这个 API 中,我使用 Github 的 OAuth 进行身份验证,并使用 express-session 来存储会话。如何测试此端点:

export async function createProject(req: Request, res: Response) {
  try {
    const { name, repository_url, repository_provider, assets_path } = req.body;
    const newProject = await Project.create({
      owner_id: (req.user as User).id,
      name,
      repository_url,
      repository_provider,
      assets_path,
    });
    const newMember = await ProjectMember.create({
      project_id: newProject.id,
      member_id: (req.user as User).id,
      project_role: "owner",
    });
    newProject.save();
    newMember.save();
    res.status(201).json(newProject);
  } catch (error) {
    res.status(400).json({ error: error.message || "Unexpected error." });
  }
}

当我没有设置 req.user 时,我通过登录 GitHub 得到了这个?

这是我现在的测试套件。我将 Jest 用于套件,使用 TypeORM 来操作 MySQL 数据库。

let server: Express;
let connection: Connection;

beforeAll(async () => {
  connection = await createConnection();
  server = await createServer();

  await connection.createQueryBuilder().delete().from(User).execute();
  await User.create({
    name: "test",
    github_name: "test",
  }).save();
});

afterAll(async () => {
  await connection.dropDatabase();
  await connection.close();
});

describe("POST /projects", () => {
  it("should return 201 & create project & valid response if not logged in", async (done) => {
    request(server)
      .post("/api/projects")
      .send({
        name: "test",
        repository_url: "https://github.com/test/test",
        repository_provider: "github",
        assets_path: "/assets/i18n"
      })
      .expect("Content-Type", /json/)
      .expect(201)
      .end((err, res) => {
        if (err) return done(err);
        done();
      });
  });
});

【问题讨论】:

    标签: node.js typescript jestjs


    【解决方案1】:

    一种可能的选择是模拟 github auth 中间件并像这样手动设置 req.user:

    // server.js
    const createServer = (middleware = []) => {
      const server = express();
      middleware.forEach(item => server.use(item));
    
      ...
      return server; 
    };
    
    // server.test.js
    describe("POST /projects", () => {
      let server;
      let middleware = [];
    
      beforeAll(() => {
        middleware = [
          express.json(),
          (req, res, next) => {
            req.user = { id: 1, name: "Username" };
            next();
          }
        ];
        server = createServer(middleware);
      });
    
      it("should return 201 ...", async () => { ... });
    });
    
    

    您也可以查看example

    【讨论】:

    • 我已经尝试过这样做,但在我的端点中,req.user 仍未定义。
    • 看来你的服务器路由是在createServer中设置的。您需要在配置路由之前使用该中间件(例如,通过向 createServer 提供额外的参数)。修正了我的答案并提供了一个沙盒示例。希望对您有所帮助。
    猜你喜欢
    • 2015-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-02
    • 2020-02-15
    相关资源
    最近更新 更多