覆盖 JS 中特定单元测试用例的 sinon 存根
Override sinon stub for a particular unit test case in JS
我有一个函数,从 json 文件读取后 returns 产品列表。
我创建了一个存根来模拟 fs.readfile 的行为,但我想检查函数抛出的异常,为此我想将默认存根覆盖为 return 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);
});
});
如何使第二个存根工作。非常感谢任何帮助
如果您只 stub/mock 一个依赖项一次,然后在每个测试用例之前重置该 stub/mock ,那么测试会更好。定义依赖项应该为每个测试用例做什么。
// 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);
});
});
我有一个函数,从 json 文件读取后 returns 产品列表。
我创建了一个存根来模拟 fs.readfile 的行为,但我想检查函数抛出的异常,为此我想将默认存根覆盖为 return 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);
});
});
如何使第二个存根工作。非常感谢任何帮助
如果您只 stub/mock 一个依赖项一次,然后在每个测试用例之前重置该 stub/mock ,那么测试会更好。定义依赖项应该为每个测试用例做什么。
// 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);
});
});