2

I am currently trying to test my typescript functions using Jasmine:

//AB.ts

export async function A() {
}
export async function B() {
    A();
}

I am trying to unit test the function B by mocking out A. I want to see if A is called. Here is what I have:

//AB.spec.ts
import * as AB from './AB'

describe('AB has a function B that ', () => {
    it('calls A', async () => {
        let ASpy: jasmine.Spy;
        ASpy = spyOn(AB, 'A').and.returnValue(Promise.resolve({}));
        await AB.B();
        expect(ASpy).toHaveBeenCalled();
    });
});

When I run this test, I am told that ASpy was never called. However upon further investigation, I found that the A function was definitely called. So it seems like the A function was called but the mock I created for the function was not triggered. I've tried implementing the A function in a different file and calling that in B and mocking that out in AB.spec.ts; in that scenario, the test passes as the expect determines that the ASpy was called. I'm not sure why having the two functions in the same file together breaks the test but putting them in separate files passes the tests. Anyway, I'm hope to hear from someone soon! I'm fine with putting the functions in separate files but I want to avoid it as much as possible in future projects.

Sean
  • 592
  • 4
  • 9
  • 19

2 Answers2

0

I see that you are using

Aspy = spyOn(AB,'A'); 

where AB is not an object of a component / class, but it is just a constant that you've used to import these global functions to your spec file.

So the problem really doesn't lie with any of your code for testing "async" functions specifically, but it lies with the way you are creating spies for your functions without class / component objects. You might want to check this thread and modify your original solution to see if revisiting your spies using one of the solutions in the below thread, allows your original tests to run fine..

Using Jasmine to spy on a function without an object

AkshAy Agrawal
  • 163
  • 1
  • 8
  • Unfortunately, that does not answer the crux of this question as to why I can't mock out A inside of my B unit test. – Sean Mar 29 '21 at 21:22
  • Yes, I may have impulsively suggested something that works for me. But anyway, I am editing my answer with some more suggestions. Please let me know if it explains the reason for your tests not working fine. – AkshAy Agrawal Mar 30 '21 at 10:13
  • @Sean Did you happen to check my edited answer on this post ? I think you may find it helpful. Nevertheless, I'd love to know if you were able to determine the root cause. – AkshAy Agrawal Apr 03 '21 at 11:40
0

I was able to find a way to properly mock out A inside of B. Just needed to add the exports keyword to my function call:

export async function B() {
    exports.A();
}

This allows the scope of B to see the definition of A while also allowing the .spec file to see that A is reverencing the exported method of A.

Sean
  • 592
  • 4
  • 9
  • 19