How to trigger a watcher in a composable while unit testing

Hi guys,

I am writing a test for the following composable:

import { useRouter } from "@/app/shared/composables/router/useRouter.js";
const { routeQueryObject } = useRouter();

export function useTable() {
  const filters = ref({});

  watch(routeQueryObject,
    () => {
      initFilters();
    },
    {
      immediate: true
    }
  );

  function initFilters() {
    let val = {...routeQueryObject.value};
    delete val.sort;
    externalActiveFilters.value = {...val};
  }
}

Here is the dependency:

import router from "@/app/router.js";
const $route = () => router.app._route;

export function useRouter(){
  const routeQueryObject = computed({
    get() {
      return $route().query;
    },
    set(val) {
      router.push({query: { ...val }});
    }
  });

return {
    routeQueryObject,
  };
}

Here is how I mock routerQueryObject:

jest.mock('.././router/useRouter.js', () => ({
  useRouter: jest.fn(() => {
    console.log('useRouter mock called');
    return {
      routeQueryObject: {
        value: { page: 1, size: 10, start: 11111110, end: 11111112, sort: "column1,asc"}
      },
    }
  })
}))

How can I trigger the watcher? I tried using .push directly, I tried mutating the routeQueryObject object directly - no success.
IRL I have a function in useRouter that updates routeQueryObject, but since it is a unit test, I don’t feel it’d be right to use it.

I had a similar problem with the watcher function not being triggered.
Vue 2.7, @vue/test-utils@1.0.3
TL;DR Turned out to use await localVue.nextTick();

First I’ve added some console.logs to my watcher function and just before expect(), and noticed their order was reversed. Then I found out, that I need to add await localVue.nextTick();, so I’m leaving it for someone who might have the same issue. :slight_smile:

Example:

import CompositionApi from '@vue/composition-api';
import { createLocalVue } from '@vue/test-utils';

const localVue = createLocalVue();
localVue.use(CompositionApi);

  it('some test', async () => {
    // use the composable and do things that will trigger the watch
    await localVue.nextTick();  // <- this is what you might be missing in your test
    expect(callback).toHaveBeenCalledTimes(1);
  });