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

Bug: Test inner function of setup in Vue 2.7/3? #1710

Closed
targetlucked69 opened this issue Aug 7, 2022 · 7 comments
Closed

Bug: Test inner function of setup in Vue 2.7/3? #1710

targetlucked69 opened this issue Aug 7, 2022 · 7 comments
Labels
bug Something isn't working

Comments

@targetlucked69
Copy link

Subject of the issue

Unable to mock inner function called by a returned function

Steps to reproduce

export default {
  setup() {
    function outer() {
      inner();
    }
    function inner() {
      // do something for only outer function
    }
    return { outer, inner };
  }
};
test('should whatever', async () => {
  const actionSpy = jest.spyOn(wrapper.vm, 'inner')
  wrapper.vm.outer()
  expect(actionSpy).toHaveBeenCalled()
})

Expected behaviour

It should have been called

Actual behaviour

expect(jest.fn()).toHaveBeenCalled()

Expected number of calls: >= 1
Received number of calls:    0
@targetlucked69 targetlucked69 added the bug Something isn't working label Aug 7, 2022
@LinusBorg

This comment was marked as off-topic.

@LinusBorg
Copy link
Member

LinusBorg commented Aug 7, 2022

That kind of mock is technically impossible in JS. The mock replaces the content of the inner property of the vm, but outer has its own direct reference to inner, and that can't be mocked/stubbed or otherwise changed.

@targetlucked69
Copy link
Author

targetlucked69 commented Aug 7, 2022

if you need to (which you usually should not) test an implementation detail of your unit ( the component) in isolation, turn it into a unit you can test - i.e. extract it into a composable function.

@LinusBorg your deleted comment might actually be the case. I have to separate that inner and outer functions to a composable so I can test it like

const mockInner = jest.fn()
jest.mock('./composables/use-something', () => ({
  useSomething: () => ({
    inner: mockInner,
    outer: jest.fn()
  }),
}))

which works..

so If I don't want it to be a composable because it's only used in a single file... the only solution I guess is to add a methods property (Options API) and put the inner and outer functions there. Jest was able to spy if it's in the methods

{
    methods: {
    inner() {
      console.log(123)
    },
    outer() {
      inner()
    }
  }

@cexbrayat
Copy link
Member

@walmartwarlord I'm off work, so I read quickly through the issue, but I think what you want to do should work (with latest Vue 3 and VTU 2)

See the unit test I added here in VTU to check that we support it: https://github.com/vuejs/test-utils/blob/main/tests/vm.spec.ts#L28-L47
It currently uses Vitest in this repo, but it's working with Jest v25+.

If that is not the case, can you provide a repro (ideally a failing test based on this stackblitz)?
I'll take a look when I get back to work.

@targetlucked69
Copy link
Author

targetlucked69 commented Aug 8, 2022

Thanks @cexbrayat. The thing is I am using VTU 1, and I just posted the question here since VTU repo looks unmaintained.

I checked the link and looks like I can just apply the implementation of allow spying on vm. Can you point me, if it's okay, which file should I check to check the implementation? Is it this one? https://github.com/vuejs/test-utils/blob/main/src/mount.ts#L553

Thank you!

@cexbrayat
Copy link
Member

I added this test to fix a regression with recent versions of jest (see #310). That might not be needed in VTU v1

In any case, you should open your issue on
https://github.com/vuejs/vue-test-utils as it is a different project/maintainer team

Thanks!

@targetlucked69
Copy link
Author

I created a basic test here @cexbrayat https://stackblitz.com/edit/vitest-dev-vitest-zmckj4

So basically I can just move those functions to a composable so I can mock it... but I have tons of components and those functions are only used in that component so I don't see moving it to a composable making sense...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants