【问题标题】:Jest Mocking Nested Singleton Dependency笑话嵌套单例依赖
【发布时间】:2020-11-28 14:41:19
【问题描述】:

我对 Jest 还很陌生,并且正在努力理解测试使用 MongoDb 等嵌套依赖项的代码的正确方法。

这是我的文件层次结构

src/getOrder/index.js

src/singletons/index.js getOrder/index.js 创建和使用的单例

我的getOrder/index.js 看起来像这样

const { getSuper, catchError } = require('../singletons');

module.exports = async function (context, req)
{
    let response = {}

    if (req.body.guid)
    {
        try
        {
            response = await getOrder(context, req);
        }
        catch (err)
        {
            response = catchError(context, err)
        }
    }
    else
    {
        response.data = 'Missing Payload'
        response.status = 400;
    }

    context.res =
    {
        status: response.status,
        headers: { 'Content-Type': 'application/json' },
        body: response
    }
}

async function getOrder(context, req)
{
    //get API singleton 
    let sd = await getSuper()

    //get order
    let res = await sd.get(`/orders/${req.body.guid}`);

    //return
    return { 'status': res.status, 'data': res.data };
}

然后我的singletons/index.js 看起来像这样

const axios = require('axios');
const https = require('https');
const MongoClient = require('mongodb').MongoClient;
const DateTime = require('luxon').DateTime

const dbOptions =
{
    useUnifiedTopology: false,
    useNewUrlParser: true
};

//singleton variables

//mongo db connection
let db;

//super connection
let sd = {};

async function getDb()
{
    //establish db connection if one isn't present
    if (!db)
    {
        const client = new MongoClient(process.env.dbUri, dbOptions);
        db = await (await client.connect()).db(process.env.dbName)
    }
    return db;
}

async function getSuper()
{
    if (sd.exp && sd.exp > DateTime.local().toString().substr(0, 19))
    {
        return sd.instance;
    }
    else
    {
        //get db connection
        let db = await getDb()

        //get token
        let token = await db.collection('secrets').findOne({ 'name': process.env.SDAccessToken })

        //set exp time
        sd.exp = token.exp;

        if (!sd.instance)
        {
            //creat axios instance
            sd.instance = axios.create({
                baseURL: process.env.SDApiUrl,
                httpsAgent: new https.Agent({ keepAlive: true }),
                headers: { 'Content-Type': 'application/json' }
            })

            //set token
            sd.instance.defaults.headers.common['Authorization'] = `Bearer ${token.value}`
        }
        else
        {
            //update token
            sd.instance.defaults.headers.common['Authorization'] = `Bearer ${token.value}`
        }

        return sd.instance;
    }
}

function catchError(context, err)
{
    let response = {}

    if (err.response && err.response.data)
    {
        response.status = err.response.status
        response.data = err.response.data
        context.log(response)
    }
    else
    {
        context.log(err)
        response.status = 500
        response.data = err
    }

    return response;
}

module.exports =
{
    getDb,
    getSuper,
    catchError
}

注意当sd 单例被初始化时,它也使用db 单例(它调用getDb) 所以我不确定如何从我的测试文件中模拟其中任何一个。我正在尝试使用@shelf/jest-mongodb 来模拟我的数据库,但是我很不确定如何在模拟getDb 函数下变成一个单例,该函数将位于测试之外的某个地方(因此它可以在其他测试中重用,等等)

【问题讨论】:

    标签: javascript node.js unit-testing jestjs mocking


    【解决方案1】:

    基本上我发现只要你在jest.config.js 文件和jest-mongodb-config.js 文件中配置了我正在使用的模拟包(@shelf/jest-mongodb),那么它就会模拟它所在的数据库功能初始化。无论是直接在您的测试中,还是在您的项目文件夹深处的 5 个嵌套子模块中

    【讨论】:

      猜你喜欢
      • 2016-08-03
      • 1970-01-01
      • 2011-10-05
      • 2021-10-18
      • 1970-01-01
      • 1970-01-01
      • 2014-10-02
      • 2014-11-19
      • 1970-01-01
      相关资源
      最近更新 更多