javascript - 覆盖 JS 中特定单元测试用例的 sinon 存根
问题描述
我有一个从 json 文件读取后返回产品列表的函数。
我创建了一个存根来模拟 fs.readfile 的行为,但我想检查函数抛出的异常,为此我想覆盖默认存根以返回 null。我如何实现这一目标
我的功能
async getAllProducts() {
try {
// let rawData = fs.readFileSync("data/products.json");
// let data = JSON.parse(rawData);
// return data;
return JSON.parse(await fs.promises.readFile("data/products.json"));
} catch (error) {
if (error.message === "Unexpected end of JSON input") {
throw new NoProductsExistError("The File is Empty");
}
throw new FileReadingError("Error Reading File");
}
}
我的 spec.js 文件
// const assert = require("assert");
const chai = require("chai");
const expect = chai.expect;
const sinon = require("sinon");
const dao = require("./dao");
const fs = require("fs");
var sandbox;
beforeEach(() => {
sandbox = sinon.createSandbox();
sandbox
.stub(fs.promises, "readFile")
.withArgs("data/products.json")
.returns(
JSON.stringify([
{
productId: 101,
productName: "Sony XB450AP Wired Headset",
},
{
productId: 102,
productName: "Sony 1000XM3 Wired Headset",
}
])
);
});
describe("getAllProducts", () => {
it("should return all products", async () => {
// Here we are using the default stub of sinon got from the beforeEach
expect(await dao.getAllProducts()).to.deep.equal([
{
productId: 101,
productName: "Sony XB450AP Wired Headset",
},
{
productId: 102,
productName: "Sony 1000XM3 Wired Headset",
}
]);
});
it("should throw Error on Empty File", async () => {
// WANT TO OVERRIDE THE DEFAULT STUB TO RETURN NOTHING
// BELOW STUB DOES NOT WORK AND GIVES "TypeError: Attempted to wrap readFile which is already wrapped" ERROR
sinon
.stub(fs.promises, "readFile")
.withArgs("data/products.json")
.returns();
expect(await dao.getAllProducts()).to.throw(NoProductsExistError);
});
});
如何使第二个存根工作。任何帮助深表感谢
解决方案
如果您只对依赖项进行一次存根/模拟,然后在每个测试用例之前重置该存根/模拟,则更好地进行测试。定义依赖项应该为每个测试用例做什么。
// const assert = require("assert");
const chai = require("chai");
const expect = chai.expect;
const sinon = require("sinon");
const dao = require("./dao");
const fs = require("fs");
describe("getAllProducts", () => {
var sandbox;
var fsReadFileStub;
before(() => {
sandbox = sinon.createSandbox();
fsReadFileStub = sandbox.stub(fs.promises, "readFile")
});
afterEach(() => {
fsReadFileStub.reset();
})
it("should return all products", async () => {
fsReadFileStub.withArgs("data/products.json")
.returns(
JSON.stringify([
{
productId: 101,
productName: "Sony XB450AP Wired Headset",
},
{
productId: 102,
productName: "Sony 1000XM3 Wired Headset",
}
])
);
expect(await dao.getAllProducts()).to.deep.equal([
{
productId: 101,
productName: "Sony XB450AP Wired Headset",
},
{
productId: 102,
productName: "Sony 1000XM3 Wired Headset",
}
]);
});
it("should throw Error on Empty File", async () => {
fsReadFileStub
.stub(fs.promises, "readFile")
.withArgs("data/products.json")
.returns();
expect(await dao.getAllProducts()).to.throw(NoProductsExistError);
});
});
推荐阅读
- html - 如何制作响应式框尺寸
- c# - 当我调用例程打开 Excel 工作簿时,它将复制 form1 上的所有控件,并打开工作簿
- php - PHP 文件不会在 nginx 中自动加载
- javascript - React-quil nextjs 使用问题参考不起作用
- ansible - 安西布尔。重新连接 playbook 连接
- javascript - 如何使用 Javascript 中的单击事件反复更改 div 的背景样式?
- git - 仅将最后 n 次提交移动到其他分支
- amazon-web-services - 有没有办法在 AWS SQS 中的消息之间添加计时器?
- docker - 无法在 kafka connect docker 映像中运行 kafka connect datagen
- spring-boot - 使用 JWT 进行身份验证如何在 Spring Boot 中工作