简体   繁体   中英

Override sinon stub for a particular unit test case in JS

I have a function which returns list of products after reading from a json file.

I have created a stub to mock the behaviour of fs.readfile but I want to check the exception thrown from the function and for that I want to override the default stub to return null. How do I achieve this

my function

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

my spec.js file

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

How do I make the second stub work. Any help is much appreciated

It is better for testing if you stub/mock a dependency only once and then reset that stub/mock before each test case. Define what the dependency should do for each test case.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM