function mocking using jest fails
file A - class Scanner
has Scanner.useScan()
method, that uses scan()
from fileB, but is not injected as parameted, and used using import
.
file B - has export const scan = () => {}// omit
arrow function
test T - tests Scanner
class from file A, including useScan()
in T, scan
is imported using import {scan} from './B'
then mocked using jest
// T.spec.ts
jest.mock('./B', () => ({
scan : jest.fn()
})
however, original function from file B, not the mocked function, is used when testing. This is because we can't DI scan()
function at test file, and is instead imported from file A.
// A.ts
import {scan} from './B'
import {scan} from './B'
and
import * as scanModule from './B'
has different internal workings.
first one imports only the function to a variable. So if we mock it, it will stay inside current context.
However, second one imports the entire module as an object. So if we mock it, the mocked module will be use even if it is used in a different file.
If useScan()
takes scan()
as argument,
// A.ts
// import {scan} from './B'
class Scanner {
////
useScan(scanFunc: scanFuncType){
////
scanFunc() // omit detai;s
}
we can use mocked version of scan()
as argument for useScan()
instead of actualscan()
in test file
do either
// T.spec.ts
import * as ScanModule from './B'
jest.mock('./B', ()=>({
scan: jest.fn()
}))
// T.spec.ts
jest.mock('/B')
import {scan} from './B'
then test
// T.spec.ts
describe('useScanner', () =>{
testScanner.useScan() // now uses mocked version of `scan()`
expect(scan).toHaveBeenCalled() // `scan` name can vary
})