question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. Itย collects links to all the places you might be looking at while hunting down a tough bug.

And, if youโ€™re still stuck at the end, weโ€™re happy to hop on a call to see how we can help out.

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 in mockReset()though, please read the first comment

I 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

peripheral.ts Lines 10-35

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");
});

peripheral.ts Line 13

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);

peripheral.ts Line 26-27

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 ๐Ÿ™ƒ๐Ÿ™ƒ๐Ÿ™ƒ");

index.ts line 75

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 and 22 of src/__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:open
  • Created 4 years ago
  • Reactions:2
  • Comments:6

github_iconTop GitHub Comments

3reactions
jayfunkcommented, Apr 8, 2021

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 to null after calling mockRestore. I have found that calling jest.restoreAllMocks() will do what mockRestore or mockReset on the individual spy should do. Seems like it might be an issue only with spy instance.

0reactions
LukasBombachcommented, Sep 5, 2019

Nono, @SimenB gets it right. I will assemble a small repo for production, give me a little time.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Mock Functions - Jest
mockReset () does, and also restores the original (non-mocked) implementation. This is useful when you want to mock functions in certain testย ...
Read more >
Jest set, clear and reset mock/spy/stub implementation
mockClear clears only data pertaining to mock calls, which means we get a fresh dataset to assert over with toHaveBeenX methods. mockReset ......
Read more >
Which is Jest way for restoring mocked function - Stack Overflow
const myMock = jest.fn(); // ... myMock.mockClear();. To clear everything stored in the mock, try instead: myMock.mockReset();.
Read more >
Mock Functions ยท Jest
This is useful when you want to mock functions in certain test cases and restore the original implementation in others. Beware that mockFn.mockRestore...
Read more >
Mocking with Jest: Spying on Functions and Changing ...
Improve your unit testing experience by using Jest to record calls of particular methods and even changing their implementation as needed.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found