掌握chai测试.catch()块的正确使用方法
P粉242535777
P粉242535777 2023-09-02 12:25:27
[JavaScript讨论组]

我正在努力通过我的代码库的端到端测试来实现良好的覆盖率,所以我也想测试 .catch() 代码。

我的API使用node.js和mongoose。

我使用chai和mocha进行测试。

我尝试了类似以下的代码:

文件 src/controllers/user.controller.js:

const User = require("../models/user.model");

const getUser = async(req, res) => {
  try {
    const user = await User.findOne({name: req.name});
    return res.status(200).json(user);
  } catch (err) {
    // 这是我想要测试的代码
    console.error(`查找用户 ${req.name} 时出错:`, err);
    return res.status(err.code).json({ message: err });
  }
}

文件 src/models/user.model.js:

const mongoose = require("mongoose");

const UserSchema = mongoose.Schema({
  name: {
    type: String,
    required: "Name is required",
  },
});
module.exports = mongoose.model("User", UserSchema);

文件 test/user.test.js:

const chai = require("chai");
 const chaiHttp = require("chai-http");
 const spies = require("chai-spies");
 const User = require("../src/models/user.model");
 chai.use(chaiHttp);
 chai.use(spies);
 chai.should();

 describe("应处理mongoose错误", function() {
    describe("有问题的User.findOne方法", function() {
      const _User_findOne_Backup = User.findOne;
      beforeEach(function() {
        // 这个函数应该重载真正的findOne函数,但它没有成功!
        User.findOne = function() {
          return Promise.reject("强制错误");
        };
      });
      afterEach(function() { // 每个测试后恢复真正的函数
        User.findOne = _User_findOne_Backup; 
      }); 

      it("注册应该返回服务器错误", function() {
        const spy = chai.spy();
        return chai
          .request(server)
          .post("/api/getUser")
          .send({name: "Alice"})
          .then(spy)
          .catch((err) => {
            const res = err.response;
            res.should.have.status(500);
          })
          .then(() => {
            spy.should.not.have.been.called();
          })
        ;
      });
    });
  });

问题是在我的测试中,伪造的 User.findOne() 方法从未被调用:原始的mongoose findOne 方法被调用成功,所以 getUser 方法从不抛出异常,导致我的测试失败...

可能我漏掉了一些明显的东西,但我真的找不到它... :-(

如果需要更多的代码或上下文,请告诉我...

更新: 根据 @Bergi 的建议,我添加了关于我的(简化的)模型和所需模块的完整信息...

P粉242535777
P粉242535777

全部回复(1)
P粉610028841

对我来说很好用。

例如:

user.model.js

const mongoose = require("mongoose");

const UserSchema = mongoose.Schema({
  name: {
    type: String,
    required: "Name is required",
  },
});
module.exports = mongoose.model("User", UserSchema);

user.controller.js

const User = require("./user.model");

const getUser = async (req, res) => {
  try {
    const user = await User.findOne({ name: req.body.name });
    return res.status(200).json(user);
  } catch (err) {
    console.error(`Error finding user ${req.body.name}:`, err);
    return res.status(500).json({ message: err });
  }
}

module.exports = {
  getUser
}

server.js

const express = require('express');
const userController = require('./user.controller');

const app = express();

app.use(express.json())
app.post('/api/getUser', userController.getUser)

module.exports = app;

user.test.js

const chai = require("chai");
const chaiHttp = require("chai-http");
const User = require("./user.model");
const server = require('./server');
chai.use(chaiHttp);
chai.should();

describe("should handle mongoose errors", function () {
  describe("faulty User.findOne method", function () {
    const _User_findOne_Backup = User.findOne;
    beforeEach(function () {
      User.findOne = function () {
        return Promise.reject("forced error");
      };
    });
    afterEach(function () {
      User.findOne = _User_findOne_Backup;
    });

    it("signup should respond with a server error", function () {
      return chai
        .request(server)
        .post("/api/getUser")
        .send({ name: "Alice" })
        .catch((err) => {
          const res = err.response;
          res.should.have.status(500);
        })
        ;
    });
  });
});

测试结果:

  should handle mongoose errors
    faulty User.findOne method
Error finding user Alice: forced error
      ✓ signup should respond with a server error


  1 passing (21ms)

--------------------|----------|----------|----------|----------|-------------------|
File                |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
--------------------|----------|----------|----------|----------|-------------------|
All files           |    89.19 |      100 |    88.89 |    88.57 |                   |
 server.js          |      100 |      100 |      100 |      100 |                   |
 user.controller.js |       80 |      100 |      100 |       75 |               6,7 |
 user.model.js      |      100 |      100 |      100 |      100 |                   |
 user.test.js       |    88.89 |      100 |    85.71 |    88.89 |             26,27 |
--------------------|----------|----------|----------|----------|-------------------|

软件包版本:

"chai": "^4.2.0",
"chai-http": "^4.3.0",
"mongodb": "^3.6.3",
"mongoose": "^5.11.9",
"express": "^4.17.1"
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号