Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] Extend vi.fn #756

Open
sheremet-va opened this issue Feb 14, 2022 · 12 comments
Open

[Feature Request] Extend vi.fn #756

sheremet-va opened this issue Feb 14, 2022 · 12 comments
Labels
enhancement New feature or request

Comments

@sheremet-va
Copy link
Member

sheremet-va commented Feb 14, 2022

Clear and concise description of the problem

We previously had a disscussion that it would be usefull to have a method on vi.fn that will defined behaviour when the function is called with this arguments.

Suggested solution

For example:

Instead of this

vi.fn((arg1) => {
  if(arg1 === '3') return true
  if(arg1 === '4') return false
  return null
})

We can wright something like this (API is not finalized):

vi.fn()
  .mockReturn(null)
  .on('3').mockReturn(true)
  .on('4').mockReturn(false)

Also does anyone else think that vi.fn API is too verbose? Maybe we can tighten it a bit. Would love to see suggestions and thoughts. For example:

  • vi.fn().returns(true) instead of vi.fn().mockReturnValue(true)
  • vi.fn().rejects(new Error()) instead of vi.fn().mockRejectValue(new Error())
  • vi.fn().resolves(true) instead of vi.fn().mockResolveValue(true)

This issue is open for other extensions. I would like to see all of the problems people face and create issues accordingly.

@sheremet-va sheremet-va added the enhancement New feature or request label Feb 14, 2022
@Demivan
Copy link
Member

Demivan commented Feb 14, 2022

I like the idea.
Another cool API could be verify or something like that. It will check that all setups were called.
Idea stolen from C# Moq library - I'm using it in almost every test.

const mock = vi.fn()
  .on('3').mockReturn(true)
  .on('4').mockReturn(false)

mock('3')

mock.verify() // Throws "Function was set up but not called with arguments '4'"

I really like Moq API https://github.com/Moq/moq4/wiki/Quickstart but I'm not sure how much can be ported to JS land.

@patak-dev
Copy link
Member

I like the idea of mock.verify(), or verifyMock(mock)

About an API to define the mapping, maybe we should leave that for user-land? Because your example could be a stand alone utility that generates the implementation:

vi.fn(
  mon().mockReturn(null)
  .on('3').mockReturn(true)
  .on('4').mockReturn(false)
)

Or it could be based on an array

vi.fn(mockFrom([
  { return: null },
  { when: '3', return: true },
  { when: '4', return: false }
])

Maybe when we get pattern matching in JS users could reach for it https://github.com/tc39/proposal-pattern-matching? I kind of like the simplicity of a function and letting the user do whatever they want inside here.

@Demivan
Copy link
Member

Demivan commented Feb 17, 2022

+1 for making it a separate library. It would be useful with other test runners too.

By the way, there it a MoqJS library: https://github.com/slavik57/moqjs. I did not think it would be possible to implement it in js land.

@sheremet-va
Copy link
Member Author

sheremet-va commented Feb 17, 2022

-1 for a separate package (or we should at least use it by default)
I think we can give better DX out of the box instead of outdated jest model. Having it is good for easier migration, but I think it lacks a little bit with its API

chaii3 pushed a commit to chaii3/vitest that referenced this issue May 13, 2022
Co-authored-by: eliarege <ege.iliklier@eliarge.com>
@rogatty
Copy link

rogatty commented Aug 21, 2022

I found this issue when looking for a Vitest based alternative for https://github.com/timkindberg/jest-when. I guess I have to migrate to a list of ifs, but hopefully this library can serve as an inspiration.

@travi
Copy link

travi commented Sep 1, 2022

i'm also looking for a vitest alternative for jest-when or sinon's .withArgs. use of conditional stubs like this helps to encourage state based testing better since separate call verification can encourage unwanted side-effect based behavior.

an api like jest-when can greatly simplify the complexity that grows quickly when implementing similar conditional behavior inside of .mockImplementation. lack of this ability is the main hesitation i currently have when considering moving tests using either sinon with .withArgs or jest tests using jest-when over to viteset.

@sheremet-va
Copy link
Member Author

sheremet-va commented Sep 2, 2022

I guess I have to migrate to a list of ifs

i currently have when considering moving tests using either sinon with .withArgs or jest tests using jest-when over to viteset

I'm pretty sure you can use jest-when with Vitest. Vitest was design to be used with libraries in jest ecosystem.

@travi
Copy link

travi commented Sep 2, 2022

I'm pretty sure you can use jest-when with Vitest. Vitest was design to be used with libraries in jest ecosystem.

i hoped for the same the last time i tried, but ran into errors when attempting to incorporate it. it has been a bit since i've attempted, so i'll try it again and bring back some detail of the error specifics.

@sheremet-va
Copy link
Member Author

i hoped for the same the last time i tried, but ran into errors when attempting to incorporate it. it has been a bit since i've attempted, so i'll try it again and bring back some detail of the error specifics.

Yeah, looking at the source code you might have errors. #1956 is meant to fix this, but we haven't released new version yet

@travi
Copy link

travi commented Sep 2, 2022

#1956 is meant to fix this, but we haven't released new version yet

great to hear! i'll watch for the next release and give it a shot. thanks!

@travi
Copy link

travi commented Sep 4, 2022

with v0.23.0 available, i was able to use jest-when with one of my simple projects: form8ion/vitest@1dc288b

i did have to enable globals for it to work, but seems to work as expected after that. thanks!

@MWhite-22
Copy link

Replying to this issue as we are in the process of refactoring a jest codebase into vitest.

One of the issues we found is jest-when is used everywhere throughout our test files, which we don't want to refactor out yet, but @types/jest-when is overwriting the global vitest types with their jest equivalents (describe, test, expect, etc.)

Temporary fix is patching the @types/jest-when, but given that our developers like the functionality of when(x).calledWith, it would be great if the vitest mock fns had that either built in, or a type safe version could be added to extend vi.fns. Without relying on (or being named) jest.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

6 participants