Sean Delaney
Sean Delaney

Reputation: 327

Unit Testing VueJS - Checking for an element with a certain class name

I'm struggling to get a simple unit test working in a VueJS app.

I'm basically trying to test the template and check if it contains a div element with a class name of "version" but the test keeps failing with an undefined is not a constructor (evaluating 'expect(component.$el.querySelector('div')).to.have.className('version')'). error.

It's a simple component with this as the template:

<template>
    <div>
        <div class="version">
            <label>Version {{ version }}</label>
        </div>
        <div class="activityBanner">
            <label>{{ user }}</label>
            <router-link id="logout" :to="{name: 'logout' }">
                <label>Logout</label>
            </router-link>
        </div>
    </div>
</template>

Here is the unit test I'm working with:

import Vue from 'vue';
import router from '@/router';
import VueRouter from 'vue-router';
import Navigation from '@/components/Navigation';

describe('Navigation.vue', () => {
  // Nice little helper to return our component within a div
  const getComponent = data => {
    const Constructor = Vue.extend(Navigation);

    return new Constructor({
      router
    }).$mount();
  };

  describe('Component', () => {
    it('should have a property "name"', () => expect(Navigation.name).to.be.a('string'));

    it('should have a property "name" set to "Navigation"', () => expect(Navigation.name).to.equal('Navigation'));

    it('should have a data hook', () => expect(Navigation.data).to.be.a('function'));

    it('should have a default "currentView" set to "profileTable"', () => {
      const defaultData = Navigation.data();

      expect(defaultData.currentView).to.equal('profileTable');
    });

    it('should have a default "version" set to "0.5"', () => {
      const defaultData = Navigation.data();

      expect(defaultData.version).to.equal(0.5);
    });

    it('should have a default "user" set to "Bob Barker"', () => {
      const defaultData = Navigation.data();

      expect(defaultData.user).to.equal('Bob Barker');
    });
  });

  describe('Template', () => {
    Vue.use(VueRouter);

    it('should render correctly', () => {
      const component = getComponent();

      expect(component.$el);
    });

    it('should have a "div" element', () => {
      const component = getComponent();

      expect(component.$el.querySelectorAll('div').length);
    });

    it('should have a element with a "className" set to "version"', () => {
      const component = getComponent();

      expect(component.$el.querySelector('div')).to.have.className('version');
    });
  });
});

What are I doing wrong?

Upvotes: 1

Views: 7752

Answers (1)

JoWinchester
JoWinchester

Reputation: 437

Checkout the Vue test utils:

Vue Test Utils

It makes very light work of testing templates.

Here is there example:

import { mount } from '@vue/test-utils'
import Counter from './counter'

describe('Counter', () => {
  // Now mount the component and you have the wrapper
  const wrapper = mount(Counter)

  it('renders the correct markup', () => {
    expect(wrapper.html()).toContain('<span class="count">0</span>')
  })

  // it's also easy to check for the existence of elements
  it('has a button', () => {
    expect(wrapper.contains('button')).toBe(true)
  })
})

Upvotes: 3

Related Questions