覆盖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,}
            ]);
    });

    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,{
                productId: 102,}
        ]);
    });

    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);
    });
});

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...