0

Assume I have a class Foo that looks like this:

class Foo {
  bar() {
    return 'bar';
  }
}

Let's say I want to mock the method bar. Is there a reason to prefer one of these over the other?

jest.spyOn(Foo.prototype, 'bar').mockImplementation(() => 'baz');

vs

Foo.prototype.bar = jest.fn().mockImplementation(() => 'baz');

I tried both, and they seem to be identical.

zed917
  • 13
  • 3
  • You don't need to do either. Just pass `{ bar: jest.fn() }` as the test double. – jonrsharpe Feb 14 '23 at 22:32
  • Understood, but that isn't what I'm asking. Given the choice between the two, I'd like to know which is preferred and why, and what difference (if any) there is. – zed917 Feb 14 '23 at 22:40
  • That's why I didn't post it as an answer. SO is all about the next person with the same question, and they should hear they have better options entirely. – jonrsharpe Feb 14 '23 at 22:45

1 Answers1

0

The difference between jest.fn and spyOn was covered pretty well in this other SO question asking about the difference, and the answers do a good job covering that.

I’d say for your mockImplementation usage, the main difference is that with jest.fn you’re completely overriding the method and can’t restore the original (unless you stored it elsewhere first), whereas with spyOn you can restore the original if you wish. That would probably be the only main reason to prefer one over the other, otherwise they are identical (when using mockImplementation, since otherwise with spyOn you can get call data without changing the original implementation).

As a side note to mention some people’s preference since you asked, depending on your use case there’s a third option to just basically make a mock of Foo, with just the piece you need, as noted by jonrsharpe in their comment, like so: { bar: jest.fn() }.

David R
  • 493
  • 2
  • 8