首页 > 解决方案 > 使用 Jest 进行主干测试渲染视图 - 无法读取未定义的属性“createDocumentFragment”

问题描述

我正在尝试使用 Jest 为 Backbone/Marionette 视图编写一个非常简单的单元测试。

测试代码:

import MyView from './MyView';

describe('test of my view', function() {
  const myView = new MyView().render();
});

但这会返回以下错误TypeError: Cannot read property 'createDocumentFragment' of undefined

at buildFragment (node_modules/jquery/dist/jquery.js:4311:22)
  at domManip (node_modules/jquery/dist/jquery.js:5238:14)
  at jQuery.fn.init.append (node_modules/jquery/dist/jquery.js:5431:10)
  at jQuery.fn.init.<anonymous> (node_modules/jquery/dist/jquery.js:5525:18)
  at access (node_modules/jquery/dist/jquery.js:3642:7)
  at jQuery.fn.init.html (node_modules/jquery/dist/jquery.js:5492:10)
  at Marionette.TemplateCache.loadTemplate (node_modules/backbone.marionette/lib/core/backbone.marionette.js:1169:24)
  at Marionette.TemplateCache.load (node_modules/backbone.marionette/lib/core/backbone.marionette.js:1149:27)
  at Function.get (node_modules/backbone.marionette/lib/core/backbone.marionette.js:1111:29)
  at Object.render (node_modules/backbone.marionette/lib/core/backbone.marionette.js:1200:87)
  at child._renderTemplate (node_modules/backbone.marionette/lib/core/backbone.marionette.js:1664:38)
  at child.render (node_modules/backbone.marionette/lib/core/backbone.marionette.js:1632:12)
  at child.render (node_modules/backbone.marionette/lib/core/backbone.marionette.js:2628:51)
  at Object.<anonymous> (src/js/my.view.spec.js:22:27)

我不确定如何解决这个问题,因为我的视图非常愚蠢(输出硬编码的 html),而且问题似乎更多地出现在骨干/牵线木偶/jquery 方面而不是我的视图代码中。

MyView 代码(简化为一个按钮,但它只是许多按钮的重复):

import Marionette from 'backbone.marionette';

import { LeftMenuView as LeftMenuViewTemplate } from './templates.index';

const LeftMenuView = Marionette.LayoutView.extend({
    template: LeftMenuViewTemplate,

    ui: {
        generalButton: '.menu-general',
        generalLink: '.menu-general-link',
    },
    buttonsList: [
        'generalButton',
    ],
    events: {
    '    click @ui.generalLink': 'switchToGeneral',
    },

    initialize() {},

    onShow() {
        this.ui.navLine.height(this.ui.generalButton.innerHeight());
        this.ui.navLine.css('top', this.ui.generalButton.position().top);
    },

    _animate(target) {
        const topPos = target.position().top;
        const newHeight = target.innerHeight();
        this.ui.navLine.stop().animate({
            top: topPos,
            height: newHeight,
        });
    },

    setInactiveButtons() {
        for (let i = 0; i < this.buttonsList.length; i += 1) {
            this.ui[this.buttonsList[i]].toggleClass('active', false);
        }
    },

    switchToGeneral() {
        this.setInactiveButtons();
        this.ui.generalButton.toggleClass('active', true);
        this.trigger('changePage:toGeneral');
        this._animate(this.ui.generalButton);
    },

});

export default LeftMenuView;

以及相关的模板代码(车把 .hbs 文件):

<div class="nav left-menu">
    <div class="vertical-nav-line"> </div>
        <ul class="settings-menu">
            <li class="menu-general active"><a href="#" class="menu-general-link">{{i18n 'NavMenuGeneral'}}</a></li>
        </ul>
</div>

标签: unit-testingbackbone.jsjestjsrendermarionette

解决方案


我遇到了一个类似的问题,所以不确定这个解决方案是否适用于你的情况。就我而言,因为视图本身不包含render方法,所以我不得不在我的测试文件中模拟它。

import MyView from './MyView'

describe('test of my view', function() {
  beforeEach(function() {
    jest.spyOn(MyView.prototype, 'render').mockImplementation(jest.fn())
  })
  
  it('should render', function() {
    const myView = new MyView().render()
  })
})

推荐阅读