mockReset removes the original implementation of a spied on function instead of just mockImplementations
See original GitHub issue๐ Bug Report
Edit
turns out the problem was
mockReset()
, there might be a bug inmockReset()
though, please read the first commentI also changed the title, so this first post might be confusing. The title this first post refers to was โjest.spyOn does not call the original methodโ because this is what I thought happend. The actual issue I found though is that mockReset removed the original implementation if a method I spied on
I am trying to test if a method on a class has been called but I do not want to mock that function. I.e. I want my code to still call the original function, I only want to be able to see if it has been called appropriately.
To my understanding (and my previous experience), if i just use jest.spyOn
like so:
const connnectSpy = jest.spyOn(sblendid.adapter, "connect");
what I was describing should already be the default behavior. I.e. I should be able to write tests like this:
expect(connnectSpy).toBeCalledTimes(1);
and the interal call to
sblendid.adapter.connect()
that is part of my implementation should have been remained untouched.
But this is not happening. When I use jest.spyOn
I can see that my original implementation never gets called. When I remove jest.spyOn
I can see it gets called again.
This is my code block
itโs a few lines, so I will go through it step by step
I am spyingOn sblendid.adapter.connect
beforeAll(async () => {
const sblendid = await Sblendid.powerOn();
peripheral = await sblendid.find(name);
connnectSpy = jest.spyOn(sblendid.adapter, "connect");
});
In line 26 I am calling the method (peripheral.connect()
) that internally will call the spied on function (sblendid.adapter.connect
)
it("connects to peripheral", async () => {
await expect(peripheral.connect()).resolves.toBe(undefined);
expect(connnectSpy).toBeCalledTimes(1);
await peripheral.disconnect();
}, 10000);
Now every time I use spyOn
here my tests time out, when I remove the spy my tests work, but of course I cannot check if my method has been called. So I did some very primitive low-level debuggingโusing console.log
.
I am logging "๐๐๐ orig ๐๐๐"
whenever my original method gets called
console.log("๐๐๐ orig ๐๐๐");
And even deeper in my code I have added another console.log
console.log("๐๐๐ connect has been called ๐๐๐");
peripheral.ts (implementation file not the file from before) line 21
I can see that these lines get called when I do not spyOn
my method once I spyOn
, these logs never get printed.
To Reproduce
You can clone my repo at the given commit:
git clone git@github.com:LukasBombach/sblendid.git
git checkout 0ba503df0a27541a8ffd66aa3510cf27ac7a72bf
yarn install # you need to use yarn because this is a monorepo with yarn workspaces
cd packages/sblendid
yarn test --watch
- you can see the logs never appear
- comment out lines
13
,17
and22
ofsrc/__tests__/peripheral.ts
(the refernces to the spy) - see that the logs appear
Expected behavior
The spiedOn method should be called regardless of the spy
Link to repl or repo (highly encouraged)
https://github.com/LukasBombach/sblendid/tree/0ba503df0a27541a8ffd66aa3510cf27ac7a72bf
envinfo
System:
OS: macOS 10.14.5
CPU: (8) x64 Intel(R) Core(TM) i5-8259U CPU @ 2.30GHz
Binaries:
Node: 12.9.1 - ~/.nvm/versions/node/v12.9.1/bin/node
Yarn: 1.17.3 - /usr/local/bin/yarn
npm: 6.10.2 - ~/.nvm/versions/node/v12.9.1/bin/npm
Issue Analytics
- State:
- Created 4 years ago
- Reactions:2
- Comments:6
Top GitHub Comments
Anyone still hitting this? Using 26.6.3 and when calling
mockRestore
the original implementation is NOT being restored. In fact it is getting set tonull
after callingmockRestore
. I have found that callingjest.restoreAllMocks()
will do whatmockRestore
ormockReset
on the individual spy should do. Seems like it might be an issue only with spy instance.Nono, @SimenB gets it right. I will assemble a small repo for production, give me a little time.