Javascript – How to write a test – a class in which there is a fetch function

I can’t write a test for my class in which a function call is followed by data retrieval and another function call.

Part of my class:

class AdDrawer{
    constructor(configuration){
       this.configuration = configuration;  
       this.ads = [];
       this.type = null;
    }
    async draw(type, id){
        fetch(this.configuration)
        .then(res => res.json())
        .then(data => {  
            this.ads = data;
            this.getRandomAd(data, type, id);
        })
    }
}

I have no idea if this is a good way to do these tests. Because I’ve sent other functions now, not repeating this every time since my other functions are automatically chained from others.

/**
 * @jest-environment jsdom
 */

const AdDrawer = require('../AdDrawer');

global.fetch = jest.fn(() =>
  Promise.resolve({
    json: () => Promise.resolve({..}) // data here

data = { //data here }

 
describe("AdDrawer", () => {
   const adDrawer = new AdDrawer(data);
  
   test("Draw is defined and called with arguments", () => {
     const setDrawSpy = jest.spyOn(adDrawer, "draw");
     const setGetRandomAdSpy = jest.spyOn(adDrawer, "draw");

     const result = adDrawer.draw("wide skyscraper","ad");
     expect(result).toBeDefined();
     expect(setDrawSpy).toHaveBeenCalledWith("wide skyscraper","ad");
  
   });

   afterEach(()=>{
      jest.restoreAllMocks();
   })
//    test('Draw function calls getRandomAd', () => {
//     const adDrawer = new AdDrawer(data);
//     const getRandomAdSpy = jest.spyOn(adDrawer, 'getRandomAd');
//     adDrawer.getRandomAd(data, "wide skyscraper", "ad");
//     expect(getRandomAdSpy).toBeDefined();
// });

});

  • 1

    There’s no point in using the async keyword if you don’t use await inside the function.

    – 

  • AdDrawer.draw() doesn’t return anything. What are you expecting result to be?

    – 

  • @Barmar github.com/MichalKarczewicz/Ad-draw My script is supposed to return the drawn advertisement in the last function

    – 

  • It does the drawing. It but it doesn’t return a value that you can check with expect(...).toBeDefined().

    – 

draw needs to return the selected random ad. getRandomAd() returns this, so you need to return that to the caller.

You don’t need to use the async keyword in the draw() definition. fetch().then() returns a promise, you just return that.

class AdDrawer {
  constructor(configuration) {
    this.configuration = configuration;
    this.ads = [];
    this.type = null;
  }
  draw(type, id) {
    return fetch(this.configuration)
      .then(res => res.json())
      .then(data => {
        this.ads = data;
        return this.getRandomAd(data, type, id);
      })
  }
  // rest of class ...
}

Then you need to use an asynchronous test, as explained in Testing Asynchronous Code

describe("AdDrawer", () => {
  const adDrawer = new AdDrawer(data);

  test("Draw is defined and called with arguments", async () => {
    const setDrawSpy = jest.spyOn(adDrawer, "draw");
    const setGetRandomAdSpy = jest.spyOn(adDrawer, "draw");

    const result = await adDrawer.draw("wide skyscraper", "ad");
    expect(result).toBeDefined();
    expect(setDrawSpy).toHaveBeenCalledWith("wide skyscraper", "ad");

  });

  afterEach(() => {
    jest.restoreAllMocks();
  })
});

Leave a Comment