4

I'm trying to spyOn exported function that another function in the same file calls.

I can't seem to get Jest to use the spy at all.

Tried with a mixture of mockImplementation and mockReturnValue.

utils.ts:

export const func1 = (x: number) => {
    const y = x + 1
    return y
}

export const func2 = (a: number) => {
    const b = a + 2
    return b
}

export const func3 = (x: number, y: number) => {
    const foo = func1(x)
    const bar = func2(y)
    return foo + bar
}

utils.test.ts:

import * as sut from './utils'

describe('test', () => {
    test('func3 spys', () => {
        let func1Spy: jest.SpyInstance
        let func2Spy: jest.SpyInstance
        func1Spy = jest.spyOn(sut, 'func1').mockImplementation(() => 8)
        func2Spy = jest.spyOn(sut, 'func2').mockImplementation(() => 10)
        const result = sut.func3(1, 2)
        expect(func1Spy).toHaveBeenCalled()
        expect(func2Spy).toHaveBeenCalled()
        expect(result).toBe(6)
    })
})

Expected behavior: Jest sees that the spy'd function has been called Actual output:

Expected number of calls: >= 1
Received number of calls:    0

Commenting out the spy call assertions give me a passing test so the function is running correctly. Just without the spys

Eli Nathan
  • 1,020
  • 2
  • 13
  • 35
  • What _are_ `func1Spy` and `func2Spy`? They don't seem to be _defined_ in what you've posted, let alone wired into `func3`. But realistically you _shouldn't_ be testing `func3` against mocks of `func1` and `func2` - they're all part of the same module. – jonrsharpe Jan 21 '22 at 15:39
  • Sorry, missed that bit out. I've updated the test block to include the spy definitions. The reason i'm trying to do this is that lets say func1 and func2 did some async fetch call and I wanted to change what they returned in various test cases of func3? – Eli Nathan Jan 21 '22 at 15:51
  • So maybe the fetching should be extracted to a separate module, then you provide a test double for _that_? Note your expectation is wrong because you've written it for the real implementation, not the mock one. – jonrsharpe Jan 21 '22 at 16:12
  • Yeah, it doesn't pass either way as it fails on the spy not being called first. So the only way you're saying this can be done is to mock another module? I'm certain I've seen this pattern of being able to spy on functions when using `import * as x`? – Eli Nathan Jan 21 '22 at 16:19
  • Only if that's also how you refer to it _inside_ the module. But like most of the answers on https://stackoverflow.com/q/45111198/3001761 it's a horrible hack around a problem that improving the architecture would actually solve! – jonrsharpe Jan 21 '22 at 22:44
  • That makes sense, thanks very much @jonrsharpe – Eli Nathan Jan 22 '22 at 14:14

0 Answers0