【发布时间】: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