Unable to pass arguments to button methods in jasmine using vue and moment

Viewed 149

I have a Vue app I am trying to unit test, using jasmine/karma. Below is the code in a component:

After using v-for=(data,index) from database, I'm setting data.date in the template:

<p class="date">
  {{ dateFilter(data.date) }}
</p>

Now I can test whether a given data is in the proper format. I currently have something like this in the spec file:

import { mount } from '@vue/test-utils';
import moment from 'moment'

it('should call method', () => {
  const selector = wrapper.find('date');
 
});

How can I call the method and pass a mock parameter to test the method? Can we also import the moment js?

2 Answers

To test whether the date was rendered in the correct format:

const wrapper = mount(MyComponent, {
  propsData: {
    // assuming component has `items` prop, used in:
    // <p class="date" v-for="data in items"> {{ dateFilter(data.date) }} </p>
    items: [
      {
        id: 100,
        date: new Date('2020-12-10T12:30:45-08:00') // 12:30pm GMT-8 === 4:30pm UTC
      }
    ]
  }
})

const dateEl = wrapper.find('.date') // find first dateElement with `date` class
expect(dateEl.text()).toEqual('16:30 pm')

To test the component method directly, access the method through the wrapper's vm property:

expect(wrapper.vm.dataFilter(new Date('2020-12-10T12:30:45-08:00'))).toEqual('16:30 pm')

You should not use a method there in the first place. You should use a computed property instead

computed: {
    dateFilter() {
      return moment.unix(this.data.date).utc().format("HH:mm a");
    },
}

in the template

 <p class="date">
      {{ dateFilter }}
 </p>

Now in the test you can change the value of data.date (I guess you pass it as a prop)

import { mount } from '@vue/test-utils';
import moment from 'moment'

const wrapper = mount(YourComponent)


 it('should call method', () => {

      const localThis = { date: <date-here> }
      expect(wrapper.computed.numbers.call(localThis)).toBe(<experct-result-here>)
 
  });

UPDATE

To "solve" the problem of iterating elements requiring to pass the argument, the Vue way would be to create a component eg. and put the logic in that. it could take a data props and act like this:

Parent.vue
<display-date v-for="(data,index)in allData" :key="data.id||index" :data-prop="data" />

Then inside the display-date component you can use the logic suggested before. Please be aware of the powerful differences between computed properties and methods.

Enjoy coding!

Related