1

I'm trying to test a private function performDataAuthorization that's imported and invoked in a class method as below.

list.js

import performDataAuthorization from "./performDataAuthorization"
class List {
    init(items) {
        return new Promise((resolve, reject) => {
            performDataAuthorization(this)
                .then(() => {resolve("promise is resolved")})
                .catch((err) => {reject(err)});
        });
    }
}

Private function module which I'm trying to test imports another method authorizeData.

performDataAuthorization.js

import * as authorizeData from "./authorizeData"; 
const performDataAuthorization = () => new Promise((resolve, reject) => {
    authorizeData.retrieveData()
        .then((res)=> {
            res != "Error" ? res.stat=1 : res.stat=0;
            return  (res.stat ? resolve() : reject(res));
        })
        .catch((err) => reject(err));
});

export { performDataAuthorization as default };

I need to spy or call on the performDataAuthorization function in the spec files so I can test the authorizeData.retrieveData has been called. I have tried the following implementations but none of them worked.

specs.js

import * as performDataAuthorization from "./performDataAuthorization";

describe("", () => {
    var authorizeDataSpy;
    beforeEach(() => {
        authorizeDataSpy = jasmine.createSpyObj("authorizeDataSpy", ["retrieveData"]);
        authorizeDataSpy.retrieveData.and.returnValue(Promise.resolve(data));
    }

    // IMP 1 with default
    describe("", () => {
        beforeEach(() => {
            spyOn(performDataAuthorization, "default");
        });
        it("promise fulfilled",(done) => {
            performDataAuthorization.default(list).then(() => {
                expect(authorizeDataSpy.retrieveData).toHaveBeenCalled();
                done();
            })
        })
    });

    // IMP 2 with window
    describe("", () => {
        beforeEach(() => {
            spyOn(window, "performDataAuthorization");
        });
        it("promise fulfilled",(done) => {
            window.performDataAuthorization(list).then(() => {
                expect(authorizeDataSpy.retrieveData).toHaveBeenCalled();
                done();
            })
        })
    });

    // IMP 3 Invoking the function directly 
    performDataAuthorization(list).then(() => {
        expect(authorizeDataSpy.retrieveData).toHaveBeenCalled();
        done();
    })
});

  • Unrelated, but avoid the [`Promise` constructor antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)! – Bergi Jun 04 '21 at 16:33
  • if you can modify `performDataAuthorization.js`, you could refactor the function to a class that is instantiated with `authorizeData` as a constructor param, so you can mock it in the test, or you could even pass `authorizeData` in the `performDataAuthorization` as a param, and then mock it – germanio Jun 04 '21 at 18:19
  • Wondering about this too, but I'm importing a 3rd party function (formatDate() from @angular/common). – frIT Feb 07 '22 at 16:07

0 Answers0