Javascript: calling asynchronous code with map and testing it in Jest
I am using map() to iterate every element of an array.
Part One:
Firstly, i create a basic version of the code.
const items = ["a","b"]
const performSth = (item) => {
console.log(item)
}
const endresult = items.map((item) => {
performSth(item)
if (item == "a") {
console.log("first")
return("{1,2,3}")
} else if (item == "b") {
console.log("second")
return(1+2)
}
})
console.log(`res ${endresult}`)
The code above is able to return “res {1,2,3},3” correctly.
Then, i create a class version of the code.
class TestMe {
constructor() {
} performSth (item) {
console.log(item)
} addData (items){
try {
items.map( (item) => {
this.performSth(item)
if (item == "a") {
console.log("first")
return "{1,2,3}";
} else if (item == "b") {
console.log("second")
return 1;
}
})
}
catch (err) {
console.warn(`Error ${err}`)
}
}
}testme = new TestMe()
const items = ["a","b"]
let result = testme.addData(items)
console.log(`res ${result}`)
The code above is returning “res undefined”. The return value of map is not correct.
I modify the try block to:
try {
const retmap = items.map( (item) => {
this.performSth(item)
if (item == "a") {
console.log("first")
return "{1,2,3}";
} else if (item == "b") {
console.log("second")
return 1;
}
})
return(retmap)
}
It is able to return “res {1,2,3},1” correctly.
After, i add async function call inside the map. I keep getting the return value of “res [object Promise]”. It becomes frustrating.
After that , i found that in ES6, we can fix it by adding Promise.all to items.map.
try {
const retmap = await Promise.all(items.map( async (item) => {
await this.performSth(item)
if (item == "a") {
console.log("first")
return "{1,2,3}";
} else if (item == "b") {
console.log("second")
return 1;
}
}))
return(retmap)
}
Now it returns “res {1,2,3},1” correctly.
Part Two:
In Jest, when testing the above code, i found a peculiar problem.
const testMe = new TestMe();
let result = await testMe.addData(data);
console.log(result.length);
The result.length are printed correctly. But the following expect call is failing:
expect(result.length).to.equal(10);
TypeError: Cannot read property ‘equal’ of undefined.
To Jest, it sees result as undefined. That causes the error. To fix it, add a single argument call done
. Jest will wait until the done
callback is called before finishing the test.
it('will add amos product', async (done) => {
…
})
and add done
before calling expect.
done();
expect(result.length).to.equal(2);
That’s it.