Brian Boyko
Brian Boyko

Reputation: 637

How do you access Vue-Composition-API type refs & "data" within Jest tests?

I'm currently working on a legacy Vue project. We're using Vue 2.x w/ Typescript, with the Options API.

I'd like to make the case to switch to the Vue Component API, and so far I think it's a really compelling case - except for one drawback.

And that is - our existing tests fail. Specifically, this is because of two reasons:

  1. Tests that use mount() from '@vue/testUtils' can't use the .setData() method to set data manually (since the observable state is returned from setup(), and no longer lives in data);

Example:

// FIXME: This test fails because Vue Test Utils .setData does not work
// with the new composition API.
it("renders by default", async () => {
  await wrapper.setData({
    crosshairCoordinates: [{ x: 0, y: 0 }],
  });
  expect(wrapper.findAllComponents(ChartTooltip).length)
    .toBe(1); // -> expected 1, recieved: 0
});
  1. Tests that access a component or HTML element in the dom via findComponent() and a ref string no longer find the new style Refs

// FIXME: This test fails because Vue Test Utils findComponent doesn't work
// with the way Refs are handled with the Vue Composition API.
it("should be default and not emit event on mouse move", async () => {
  const chartWrapper = wrapper.findComponent({ ref: "wrapper" });
  chartWrapper.trigger("mousemove"); // -> TypeError Cannot read property 'ref' of undefined
  expect(wrapper.emitted("mousemove")).toBeFalsy();
});

Quite frankly, if I can figure out how to resolve these issues, I can make a full recommendation to move to the VueComponentAPI and make some developers very happy. If I can't, then I can't recommend it and will have to stick with the Vue Options API.

Any ideas?

Upvotes: 10

Views: 8493

Answers (2)

fguillen
fguillen

Reputation: 38888

I am new in Vue and I am already heading this issue. The answer looks like there is no solution

What I got from this thread is that:

setData only works with data. There isn't a good way to modify a value inside a function (like setup).

For setup, I'd generally just recommend interacting with the component via trigger or passing props to test it (like a user would).

There is probably some way to make it work using .vm, but this is not generally a good idea. vm is basically like a private variable - it's not something you can normally access in your application. Test Utils exposes it, but the majority of the time you don't need it.

One option would just be to move these out of setup and allow them to receive arguments. You could make a composable

Upvotes: 0

Rassul
Rassul

Reputation: 39

  1. instead of wrapper.setData({foo: 'bar'}) you can use wrapper.vm.foo = 'bar'
  2. i believe the behavior of wrapper.findComponent() did not change in any way. keep in mind that wrapper.findComponent({ ref: "foo" }) might return empty wrapper if the ref is not a component but an html element

Upvotes: 2

Related Questions