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();
// });
});
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();
})
});
There’s no point in using the
async
keyword if you don’t useawait
inside the function.AdDrawer.draw()
doesn’t return anything. What are you expectingresult
to be?See jestjs.io/docs/asynchronous
@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()
.Show 1 more comment