node.js - 如果我要对 if 子句中发生的事情进行单元测试,我应该将所有内容模拟到 if 子句中吗?
问题描述
场景
我正在为类似于下面的模块编写单元测试
服务.js
const client = require("./../client");
let managedData = {};
function manageData(dataId) {
let users = client.retrieveUsers(); //Will return an array of strings. For example: a list of user names
let user = client.retrieveCurrentUser(); //Will return a string. For example: one user name
let userIsPresentInList = users.includes(user); //Check if the user is present in a broader user list
if(userIsPresentInList) {
managedData[dataId] = client.retrieveDataWithId(dataId);
}
}
function unmanageData(dataId) {
client.doSomethingToTheDataWithId(dataId)
delete managedData[dataId]
}
module.exports = {
manageData,
unmanageData
}
我的一些单元测试的目标是当用户出现在用户列表中时会发生什么,即 if 子句内部会发生什么
问题是:如果我对 if 子句进行单元测试,我是否应该模拟该子句的所有内容(下面的选项 1)?或者我应该创建一种以 if 子句结尾的“直接”方式(下面的选项 2)?
考试
选项 1) 通过 describe 块对测试进行分组,并在 beforeEach/beforeAll: 中进行模拟:涉及 if 子句内部内容的场景被分组在一个 describe 块中,并且在 if 子句之前对所有语句进行模拟
选项 2) 模拟模块内部的中间函数: service.js 被重构。检查用户是否在用户列表中的代码被提取到模块内的一个新函数中。然后模拟这个函数。这样,if 子句之前的任何内容都无关紧要,测试只关注 if 子句中的内容是否有效
service.test.js
const service = require("./service");
const client = require("./../client");
jest.mock("./../client");
beforeEach(() => {
jest.clearAllMocks();
});
describe('Sucesful management', () => {
//OPTION 1
beforeEach(() => {
client.retrieveUsers = jest.fn(() => ["a", "b", "c"]);
client.retrieveCurrentUser = jest.fn(() => "a");
})
//OPTION 2
beforeEach(() => {
service.isUserPresentInUsersList = jest.fn(() => true);
})
afterEach(() => {
service.isUserPresentInUsersList.mockRestore();
})
it("Given the user belongs to the user list, should retrieve the data calleing manageData", async () => {
//Act
service.manageData("D");
//Assert
expect(client.retrieveDataWithId).toHaveBeenCalledWith("D");
});
it("Given the user belongs to the user list, should do something with the data when calling unmanageData", async () => {
//Act
service.manageData("D");
service.unmanageData("D");
//Assert
expect(client.doSomethingToTheDataWithId).toHaveBeenCalledWith("D");
});
})
在这种情况下有更好的选择吗?这些方法中的任何一个都可怕吗?
一个扩展的问题是:哪些开源项目具有良好的测试实践,我可以从中获得灵感?
解决方案
推荐阅读
- vb.net - 需要帮助了解二维数组
- java - Java - 使用 Swing 创建连续的图像幻灯片
- sql - 除了没有聚合函数的列之外,当我们在列上选择聚合函数时,是否有必要使用 GROUP BY?
- c++ - 使用 MySQL 连接器 C++ 链接 mysqlcppconn-static 时出现问题
- javascript - 将图像添加到使用 jQuery
- java - Tomcat 权限被拒绝 /home/ubuntu 无法 GET、POST
- javascript - 是否可以以编程方式判断 webp 循环何时结束?
- listview - Flutter/Firestore - 在流构建器中的动态列表视图上实现“分页”
- excel - 如何创建超链接数组(Excel VBA)?
- reporting-services - Ssrs,使用通配符计算一个文件