Express 路由器的模拟后处理程序无法按预期工作

问题描述

我有一个文档路由器,它有 router.post('/mine',[auth,uploadFile],async (req,res) => { ... }) 路由处理程序。此路由处理程序的实际实现如下。

documents.js 路由器

const createError = require('./../helpers/createError');
const auth = require('./../middlewares/auth');
const uploadFile = require('./../middlewares/uploadFile');
const express = require('express');
const router = express.Router();

router.post('/mine',res) => {
    try {
        let user = await User.findById(req.user._id);

        let leftdiskSpace = await user.leftdiskSpace();

        if(leftdiskSpace < 0) {
            await accessAndRemoveFile(req.file.path);
            res.status(403).send(createError('Your plan\'s disk space is exceeded.',403));
        } else {
            let document = new Document({
                filename: req.file.filename,path: `/uploads/${req.user.username}/${req.file.filename}`,size: req.file.size
            });
            document = await document.save();

            user.documents.push(document._id);
            user = await user.save();

            res.send(document);
        }
    } catch(ex) {
        res.status(500).send(createError(ex.message,500));
    }
});

module.exports = router;

我目前正在使用 Jest 和 Supertest 编写集成测试。我当前的 documents.test.js 测试文件如下:

documents.test.js 测试文件

const request = require('supertest');
const { Document } = require('../../../models/document');
const { User } = require('../../../models/user');
const fs = require('fs');
const path = require('path');

let server;

describe('/api/documents',() => {
    beforeEach(() => { server = require('../../../bin/www'); });
    afterEach(async () => {
        let pathToTestFolder = path.join(process.cwd(),config.get('diskStorage.destination'),'user');
        
        // Remove test uploads folder for next tests
        await fs.promises.access(pathToTestFolder)
            .then(() => fs.promises.rm(pathToTestFolder,{ recursive: true }))
            .catch((err) => { return; });

        // Remove all users and documents written in test database
        await User.deleteMany({});
        await Document.deleteMany({});

        server.close();
    });

    describe('POST /mine',() => {
        it('should call user.leftdiskSpace method once',async () => {
            let user = new User({
                username: 'user',password: '1234'
            });
            user = await user.save();

            let token = user.generateAuthToken();

            let file = path.join(process.cwd(),'tests','integration','files','test.json');

            let documentsRouter = require('../../../routes/documents');

            let errorToThrow = new Error('An error occured...');

            user.leftdiskSpace = jest.fn().mockRejectedValue(errorToThrow);
            
            let mockReq = { user: user };
            let mockRes = {};

            documentsRouter.post = jest.fn();
            documentsRouter.post.mockImplementation((path,callback) => {
                if(path === '/mine') {
                    console.warn('called');
                    callback(mockReq,mockRes);
                }
            });

            const res = await request(server)
                .post('/api/documents/mine')
                .set('x-auth-token',token)
                .attach('document',file);

            expect(documentsRouter.post).toHaveBeenCalled();
            expect(user.leftdiskSpace).toHaveBeenCalled();
        });
    });
});

我为 documents.js 路由器创建了模拟后路由器处理程序。正如您从该路由处理程序的 mockImplementation 中看到的,它检查路径是否等于 '/mine'(这是我的超级测试端点),然后调用 console.warn('called'); 和回调。当我运行此测试文件时,我看不到正文为“已调用”的任何黄色警告消息。而且当 POST 请求端点 /api/documents/mine 时,服务器不会触发我的模拟函数 documentsRouter.post。它从未被调用过。所以我认为服务器的文档路由器没有被我的模拟发布路由处理程序所取代。它仍然使用原始的 post 路由处理程序来响应我的 POST 请求。我应该如何测试我的模拟 documentsRouter.post 函数是否已被调用

请注意,我的 User 模型有一个自定义方法来检查用户的剩余磁盘空间。我也试图模拟那个猫鼬自定义方法,但它也不起作用。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...