Home > Back-end >  VueJS and Jest. Testing component with local imported mixin
VueJS and Jest. Testing component with local imported mixin

Time:10-26

I am learning VueJS by recreating MineOS interface. I have replicated a bunch of functionality without actually calling the backend. I've run into an issue with unit testing. It looks like I've done everything I can but I think that my mixin method isn't being called. I think what I am doing is:

  1. mocking the store/state with my test (which I have done in my login spec).
  2. mocking the action that the mixin uses and assigning to the store, which should be mapped in the mixin.
  3. populating the java_xmx input with 235 and then triggering the input event.
  4. trigger next tick
  5. interrogate the action to see if it's been called.

Is the only way to test with mixins to import globally and mock?

javaoptions.vue

<template>
  <div >
    <div >
      <b-dropdown
        aria-role="list"
        @change="updateConfig('java', 'jarfile', $event)"
      >
        <template #trigger="{ active }">
          <b-button
            label="Change runnable JAR to:"
            :icon-right="active ? 'menu-up' : 'menu-down'"
          />
        </template>
        <b-dropdown-item aria-role="listitem" value="minecraft_server_17.1.jar"
          >minecraft_server_17.1.jar</b-dropdown-item
        >
      </b-dropdown>
    </div>
    <div >
      <div >
        <b-field label="Memory Allocation (Heapsize)">
          <div >
            <div >
              <b-field >
                <p >
                  <b-button >-Xmx</b-button>
                </p>
                <b-input
                  id="java_xmx"
                  :lazy="true"
                  type="number"
                  @input="updateConfig('java', 'java_xmx', $event)"
                ></b-input>
                <p >
                  <b-button >MB</b-button>
                </p>
              </b-field>
            </div>
            <div >
              <b-field >
                <p >
                  <b-button >-Xms</b-button>
                </p>
                <b-input
                  id="java_xms"
                  type="number"
                  :lazy="true"
                  @input="updateConfig('java', 'java_xms', $event)"
                ></b-input>
                <p >
                  <b-button >MB</b-button>
                </p>
              </b-field>
            </div>
            <div >
              <b-field label="Additional Java arguments:">
                <b-input
                  id="java_tweaks"
                  placeholder="-XX: DisableExplicitGC"
                  :lazy="true"
                  @input="updateConfig('java', 'java_tweaks', $event)"
                />
              </b-field>
            </div>
            <div >
              <b-field label="Additional Jar arguments:">
                <b-input
                  id="jar_args"
                  placeholder="nogui"
                  :lazy="true"
                  @input="updateConfig('java', 'jar_args', $event)"
                />
              </b-field>
            </div>
          </div>
        </b-field>
      </div>
    </div>
  </div>
</template>

<script>
import updateConfigMixin from '@/mixins/updateconfig-mixin.js';

export default {
  name: 'JavaOptions',
  mixins: [updateConfigMixin],
  computed: {},
  methods: {},
};
</script>

<style lang="scss" scoped></style>

JavaSettings.spec.js

import { mount, createLocalVue } from '@vue/test-utils';
import JavaOptions from '@/components/partials/java_settings/javaoptions.vue';
import Buefy from 'buefy';
import Vuex from 'vuex';

const localVue = createLocalVue();

localVue.use(Vuex);
localVue.use(Buefy);

describe('JavaOptions.vue', () => {
  let actions;
  let store;

  beforeEach(() => {
    actions = {
      updateServerConfigAction: jest.fn(),
    };

    store = new Vuex.Store({
      actions,
      selected: { config: { java_xmx: '' } },
    });
  });

  it("expect 'updateServerConfigAction' to be called on setting change", async () => {
    const wrapper = mount(JavaOptions, {
      store,
      localVue,
      attachTo: document.body,
    });

    const java_xmx = wrapper.find('#java_xmx');
    java_xmx.element.value = 235;
    java_xmx.trigger('input');
    await wrapper.vm.$nextTick();
    expect(java_xmx.element.value).toBe('235');
    expect(wrapper.vm.updateServerConfigAction).toHaveBeenCalled();
  });
});

updateconfig-mixin.js

import cloneDeep from 'clone-deep';
import { mapActions, mapState } from 'vuex';

export default {
  computed: {
    ...mapState({ config: state => state.selected.config }),
  },
  methods: {
    ...mapActions(['updateServerConfigAction']),
    updateConfig(section, propKey, newVal) {
      const config = cloneDeep(this.config);
      const selectedSection = config[section];
      selectedSection[propKey] = newVal;
      this.updateServerConfigAction(config);
    },
  },
};

TERMINAL OUTPUT

peter@peter-VirtualBox:/usr/development/mineos-vue$ npm run -s test:unit
 FAIL  tests/unit/JavaSettings.spec.js
  ● JavaOptions.vue › expect 'updateServerConfigAction' to be called on setting change

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

    Expected number of calls: >= 1
    Received number of calls:    0

      36 |     await wrapper.vm.$nextTick();
      37 |     expect(java_xmx.element.value).toBe('235');
    > 38 |     expect(actions.updateServerConfigAction).toHaveBeenCalled();
         |                                              ^
      39 |   });
      40 | });
      41 |

      at Object.it (tests/unit/JavaSettings.spec.js:38:46)

 PASS  tests/unit/Login.spec.js
-----------------------------------|----------|----------|----------|----------|-------------------|
File                               |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
-----------------------------------|----------|----------|----------|----------|-------------------|
All files                          |       50 |      100 |    33.33 |       50 |                   |
 components/partials               |      100 |      100 |      100 |      100 |                   |
  Login.vue                        |      100 |      100 |      100 |      100 |                   |
 components/partials/java_settings |      100 |      100 |      100 |      100 |                   |
  javaoptions.vue                  |      100 |      100 |      100 |      100 |                   |
 mixins                            |        0 |      100 |        0 |        0 |                   |
  updateconfig-mixin.js            |        0 |      100 |        0 |        0 |     6,11,12,13,14 |
-----------------------------------|----------|----------|----------|----------|-------------------|

Test Suites: 1 failed, 1 passed, 2 total
Tests:       1 failed, 1 passed, 2 total
Snapshots:   0 total
Time:        1.063s
Ran all test suites.

CodePudding user response:

Figured it out finally!

There were a couple of issues that required fixing for the entire test to pass. The issue at hand was that the mixin didn't appear to be utilised in the test. I required to change @input="updateConfig('java', 'java_xmx', $event)" to @input.native="updateConfig('java', 'java_xmx', $event)" of course! .native.

I then discovered that I hadn't mocked my state and had to do that.

The final code for the test is

import { mount, createLocalVue } from '@vue/test-utils';
import JavaOptions from '@/components/partials/java_settings/javaoptions.vue';
import Buefy from 'buefy';
import Vuex from 'vuex';

const localVue = createLocalVue();

localVue.use(Vuex);
localVue.use(Buefy);

describe('JavaOptions.vue', () => {
  let actions;
  let store;

  beforeEach(() => {
    actions = {
      updateServerConfigAction: jest.fn(),
    };

    store = new Vuex.Store({
      actions,
      state: { selected: { config: { java: { java_xmx: '' } } } },
    });
  });

  it("expect 'updateServerConfigAction' to be called on setting change", async () => {
    const wrapper = mount(JavaOptions, {
      store,
      localVue,
      attachTo: document.body,
    });

    const java_xmx = wrapper.find('#java_xmx');
    await java_xmx.setValue(235);

    expect(java_xmx.element.value).toBe('235');
    expect(actions.updateServerConfigAction).toHaveBeenCalled();
  });
});
  • Related