My application uses a service that returns a promise that is typically dependant on a whole bunch of other promises. I've refactored this into seperate named functions to make testing (and readability) easier. So in this case I just want to test that the run function does its job and calls the other functions.
e.g.
run() {
return myService
.connection
.then(this.namedFunction1)
.then(this.namedFunction2)
.then(this.namedFunction3)
.catch((error) => {
console.log("doh!", error.stack);
});
When I test that namedFunction1 has been called Jasmine fails, even though this is not the case. Here is a little code example I made up to keep things simple:
getString() {
return Promise.resolve("Heeeelp. Heeeelp!!");
}
printToConsole(string) {
console.log(string); // This works! but Jasmine says nay :(
}
myFunction() {
this.getString()
.then(this.printToConsole)
.catch((error) => {
console.log("Some error occurred", error);
});
}
...and the test:
it("should call the printToConsole function", function() {
spyOn(myClass, "printToConsole").and.callThrough(); //added the call through so it would print
myClass.myFunction();
expect(myClass.printToConsole).toHaveBeenCalled();
});
and the output...
> Started F[2016-05-16 11:32:31.898] console - Heeeelp. Heeeelp!!
>
>
> Failures: 1) MyClass myFunction should call the printToConsole
> function Message:
> Expected spy printToConsole to have been called. Stack:
> Error: Expected spy printToConsole to have been called.
I've tried adding the jasmine asynch done() function but this did nothing, and ultimately I'm resolving this promise immediately in the example.
So why or how can this test be failing?
Any help would be greatly appreciated. Thanks.
Because myFunction
is an asynchronous operation. myFunction
calls an async function and then returns immediately, after which the test assertion fires. At that point, printToConsole
hasn't actually been called yet. You'll want to use Jasmine's async test support to run this test successfully.
You'll need to modify myFunction
to return the promise so you can know when it's completed:
myFunction() {
return this.getString()
.then(this.printToConsole)
.catch((error) => {
console.log("Some error occurred", error);
});
}
Then you'll modify your test to use the done
function provided by Jasmine:
it("should call the printToConsole function", function(done) {
spyOn(myClass, "printToConsole").and.callThrough(); //added the call through so it would print
myClass.myFunction().then(function () {
expect(myClass.printToConsole).toHaveBeenCalled();
done();
}).catch(done); // to make sure the test reports any errors
});
That should get things working.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With