如何测试 Vue.js 插件函数 return 文档元素?

How to test Vue.js plugin function that return a document element?

我创建了一个简单的 Vue.js 插件,并想用 npm 和 jest 对其进行测试。 一个函数应该 return 按 id 的文档元素,但它 return 总是 null。 为什么会这样,我该如何解决?

// plugintest.js

const PluginTest = {
    install(Vue, options) {
        Vue.mixin({
            methods: {
                getBool: function() { return true; },
                getElem: function(id) { return document.getElementById(id); }
            }
        });
    }
}

export default PluginTest;
//plugintest.spec.js

let Vue = require('vue/dist/vue')
import PluginTest from './plugintest.js';

Vue.use(PluginTest);

describe("plugintest.js", () => {

    test('test functions', () => {
        const wrapper = new Vue({
            template: '<div id="div1">Hello, World!</div>' }).$mount();

        expect(wrapper.getBool()).toBe(true);
        expect(wrapper.getElem('div1')).not.toBe(null); // FAIL!!!
    });
});

错误信息:

expect(received).not.toBe(expected) // Object.is equality

    Expected: not null

      19 |
      20 |         expect(wrapper.getBool()).toBe(true);
    > 21 |         expect(wrapper.getElem('div1')).not.toBe(null);
         |                                       ^
      22 |     });
      23 | });
      24 |

      at Object.toBe (plugintest.spec.js:21:39)

console.log(wrapper.$el) 输出:


HTMLDivElement {
        __vue__:
         Vue {
           _uid: 1,
           _isVue: true,
           '$options':
            { components: {},
              directives: {},
              filters: {},
              _base: [Object],
              methods: [Object],
              template: '<div id="div1">Hello, World!</div>',
              render: [Function: anonymous],
              staticRenderFns: [] },
           _renderProxy:
            Vue {
              _uid: 1,
              _isVue: true,
              '$options': [Object],
              _renderProxy: [Circular],
              _self: [Circular],
              '$parent': undefined,
              '$root': [Circular],
              '$children': [],
              '$refs': {},
              _watcher: [Object],
              _inactive: null,
              _directInactive: false,
              _isMounted: true,
              _isDestroyed: false,
              _isBeingDestroyed: false,
              _events: {},
              _hasHookEvent: false,
              _vnode: [Object],
              _staticTrees: null,
              '$vnode': undefined,
              '$slots': {},
              '$scopedSlots': {},
              _c: [Function],
              '$createElement': [Function],
              '$attrs': [Getter/Setter],
              '$listeners': [Getter/Setter],
              _watchers: [Object],
              getBool: [Function: bound getBool],
              getElem: [Function: bound getElem],
              _data: {},
              '$el': [Circular] },
           _self: [Circular],
           '$parent': undefined,
           '$root': [Circular],
           '$children': [],
           '$refs': {},
           _watcher:
            Watcher {
              vm: [Circular],
              deep: false,
              user: false,
              lazy: false,
              sync: false,
              before: [Function: before],
              cb: [Function: noop],
              id: 2,
              active: true,
              dirty: false,
              deps: [],
              newDeps: [],
              depIds: Set {},
              newDepIds: Set {},
              expression: 'function () {\n        vm._update(vm._render(), hydrating);\n      }',
              getter: [Function: updateComponent],
              value: undefined },
           _inactive: null,
           _directInactive: false,
           _isMounted: true,
           _isDestroyed: false,
           _isBeingDestroyed: false,
           _events: {},
           _hasHookEvent: false,
           _vnode:
            VNode {
              tag: 'div',
              data: [Object],
              children: [Object],
              text: undefined,
              elm: [Circular],
              ns: undefined,
              context: [Circular],
              fnContext: undefined,
              fnOptions: undefined,
              fnScopeId: undefined,
              key: undefined,
              componentOptions: undefined,
              componentInstance: undefined,
              parent: undefined,
              raw: false,
              isStatic: false,
              isRootInsert: true,
              isComment: false,
              isCloned: false,
              isOnce: false,
              asyncFactory: undefined,
              asyncMeta: undefined,
              isAsyncPlaceholder: false },
           _staticTrees: null,
           '$vnode': undefined,
           '$slots': {},
           '$scopedSlots': {},
           _c: [Function],
           '$createElement': [Function],
           '$attrs': [Getter/Setter],
           '$listeners': [Getter/Setter],
           _watchers: [ [Object] ],
           getBool: [Function: bound getBool],
           getElem: [Function: bound getElem],
           _data: {},
           '$el': [Circular] } }

我认为您缺少 getElem() 的参数,试一试:

expect(wrapper.getElem('div1')).not.toBe(null);

尝试使用 vm.$el.

expect(wrapper.$el).not.toBe(null);

The root DOM element that the Vue instance is managing.

Reference

通知

如果您想访问其他元素,您的代码可能如下所示:

expect(wrapper.$el.querySelector("div")).not.toBe(null);

另一种选择是使用 VueTestUtils 的 find 方法:https://vue-test-utils.vuejs.org/api/wrapper/find.html#find

使用 VueTestUtils

尝试使用 attachToDocument 选项。 Reference

import { mount, createLocalVue } from "@vue/test-utils";

import PluginTest from "./plugintest.js";

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

it("plugintest.js", () => {
  const component = {
    template: "<div id="div1">Hello, World!</div>"
  }

  const wrapper = mount(component, {
    localVue,
    attachToDocument: true
  });

  expect(wrapper.vm.getElem("div1")).not.toBe(null);
});