vue.js test-utils如何在已安装的生命周期挂钩中测试功能

时间:2018-10-03 15:55:03

标签: vue.js mocking vue-test-utils

在以下组件中,我想测试Mounted()挂钩中的功能(模拟它们)

ContactForm.vue

    <template>
       ...
    </template>

    <script>
    import { mapGetters } from "vuex";
    import appValidationDictionarySetup from "@/locales/appValidationDictionary";
    import router from "@/router";

    export default {
      name: "contactForm",
      $_veeValidate: { validator: "new" },
      data() {
        return {
          ...
        };
      },
      computed: {
        ...mapGetters(["language"]),
        ...mapGetters("authentication", ["loading"]),
        ......
      },
      watch: {
        language(newLanguage) {
          this.$validator.localize(newLanguage);
        }
      },
      methods: {
        ...
      },
      mounted() {
        appValidationDictionarySetup(this.$validator);
        this.$validator.localize(this.language);
      }
    };
    </script>

以下规格测试失败,因为我不知道如何模拟这两个函数:appValidationDictionarySetup()和$ validator.localize() 任何反馈表示赞赏..(我应该测试它吗?...也许是第一个提示)

ContactForm.spec.js

    import Vue from "vue";
    import Vuex from 'vuex';
    import { storeMock } from './mocks.js';
    import VeeValidate from "vee-validate";

    import i18n from "@/locales";
    import Vuetify from "vuetify";

    import { shallowMount } from "@vue/test-utils";
    import ContactForm from "@/components/Home/ContactForm.vue";

    Vue.use(Vuex);
    Vue.use(VeeValidate, { errorBagName: "errors" });
    Vue.use(Vuetify);

    describe("ContactForm.vue", () => {
      let wrapper;
      let options;
      const store = new Vuex.Store(storeMock)
      const v = new VeeValidate.Validator();

      beforeEach(() => {
        const el = document.createElement("div");
        el.setAttribute("data-app", true);
        document.body.appendChild(el);
        options = {
          sync: false,
          store,
          provide: () => ({
            $validator: v
          }),
          i18n
        }
      });

      it("Mounted", async () => {
        // given
        // when
        wrapper = shallowMount(ContactForm, options);
        // then
        console.log(wrapper.vm.$validator);
     expect(wrapper.vm.$validator.localize()).toHaveBeenCalledTimes(1);
      });
    });

console.log

    ContactForm.vue
        ✕ Mounted (281ms)

      ● ContactForm.vue › Mounted

        expect(jest.fn())[.not].toHaveBeenCalledTimes()

        jest.fn() value must be a mock function or spy.
        Received: undefined

          41 |     // then
          42 |     console.log(wrapper.vm.$validator);
        > 43 |     expect(wrapper.vm.$validator.localize()).toHaveBeenCalledTimes(1);
             |                                              ^
          44 |   });
          45 |
          46 |

          at Object.toHaveBeenCalledTimes (tests/unit/ContactForm.spec.js:43:46)
          at tryCatch (node_modules/regenerator-runtime/runtime.js:62:40)
          at Generator.invoke [as _invoke] (node_modules/regenerator-runtime/runtime.js:296:22)
          at Generator.prototype.(anonymous function) [as next] (node_modules/regenerator-runtime/runtime.js:114:21)
          at step (node_modules/@babel/runtime/helpers/builtin/asyncToGenerator.js:10:30)
          at _next (node_modules/@babel/runtime/helpers/builtin/asyncToGenerator.js:25:9)
          at node_modules/@babel/runtime/helpers/builtin/asyncToGenerator.js:32:7
          at Object.<anonymous> (node_modules/@babel/runtime/helpers/builtin/asyncToGenerator.js:5:12)

      console.log tests/unit/ContactForm.spec.js:42
        ScopedValidator {
          id: 6,
          _base:
           Validator {
             strict: true,
             errors: ErrorBag { vmId: [Getter/Setter], items: [Getter/Setter] },
             fields: FieldBag { items: [Getter/Setter] },
             paused: false,
             fastExit: true },
          _paused: false,
          errors: [Getter/Setter] }

    Test Suites: 1 failed, 1 total
    Tests:       1 failed, 1 total
    Snapshots:   0 total
    Time:        3.677s, estimated 6s
    Ran all test suites matching /ContactForm.spec.js/i.
    error Command failed with exit code 1.

更新

我尝试过:

    it("Mounted", async () => {
        // given
        const localizeMock = jest.spyOn(v, "localize");
        localizeMock.mockImplementation(() => "mock");
        // when
        wrapper = shallowMount(ContactForm, options);
        // then
        console.log(wrapper.vm.$validator);
        expect(wrapper.vm.$validator.localize()).toHaveBeenCalledTimes(1);
      });

但是失败,并显示以下错误消息

      ● ContactForm.vue › Mounted

          expect(jest.fn())[.not].toHaveBeenCalledTimes()

          jest.fn() value must be a mock function or spy.
          Received: undefined

            43 |     // then
            44 |     console.log(wrapper.vm.$validator);
          > 45 |     expect(wrapper.vm.$validator.localize()).toHaveBeenCalledTimes(1);
               |                                              ^
            46 |   });
            47 |
            48 |

更新2

我不知道它是否正确,但是我更新了mount()测试来检查validator.locale是否设置为商店值 还可以..;测试足够了吗?

    it("Mounted", async () => {
    // when
    wrapper = shallowMount(ContactForm, options);
    // then
    expect(wrapper.vm.$validator.locale).toBe("en");
    });

console.log

 PASS  tests/unit/ContactForm.spec.js
  ContactForm.vue
    ✓ Mounted (163ms)

1 个答案:

答案 0 :(得分:0)

import { shallowMount, createLocalVue } from '@vue/test-utils'
import MyComponent from '/path/to/MyComponent'

describe('MyComponent.vue', () => {
  let spy
  let localVue

  beforeEach(() => {
    spy = jest.spyOn(MyComponent.methods, 'the_name_of_the_method_called_on_mount')

    localVue = createLocalVue()

    wrapper = shallowMount(MyComponent, {localVue})
  })

  it('the_name_of_the_method_called_on_mount is called on mount!', () => {
    expect(spy).toHaveBeenCalled()
  })
})