在节点的mocha js中使用全局窗口变量

时间:2015-03-29 02:11:28

标签: javascript node.js backbone.js mocha chai

我是js单元测试的新手,我正在尝试使用mocha作为我在this github repo找到的主干联系人管理器教程。但是,我有一个全局window.ContactManager变量,我想要测试它是否存在,然后测试启动函数内的router.on功能。变量看起来像这样:

  window.ContactManager = {
  Models: {},
  Collections: {},
  Views: {},

  start: function(data) {
    var contacts = new ContactManager.Collections.Contacts(data.contacts),
        router = new ContactManager.Router();

    router.on('route:home', function() {
      router.navigate('contacts', {
        trigger: true,
        replace: true
      });
    });

    router.on('route:showContacts', function() {
      var contactsView = new ContactManager.Views.Contacts({
        collection: contacts
      });
.....

我的测试不起作用: var expect = require('chai')。expect;

describe("Application", function() {
    it('creates a global variable for the name space ContactManager' , function () {
        expect(ContactManager).to.exist;
    })
});

如何通过在控制台中运行测试来测试和访问mocha中的全局窗口变量?

2 个答案:

答案 0 :(得分:12)

您忽略了在浏览器中运行JavaScript代码和在Node中运行JavaScript代码之间的区别。

在浏览器中,window名称是对象的引用,该对象包含所有全局变量。因此,当您在最外层范围内执行foo = 1时,您会声明一个全局foo,该window.foo也可以作为window.bar = 1访问。相反,如果您指定一个新字段:bar,那么您将拥有一个名为global的新全局。

在Node中,您的全局对象将以foo = 1的形式进行访问。因此,如果您在最外层范围内fooglobal.foo也可以global.bar = 1访问。如果您执行bar,则会有一个名为window的新全局。

您的代码显示您修改了window对象,该对象似乎不是对全局对象的引用。选项:

  1. 在浏览器中而不是在Node中运行Mocha。请参阅Mocha's documentation

  2. 设置您的Node环境,使其模仿足够的浏览器环境以满足节点。将全局global变量设置为等于window 可能已足够但我不知道Backbone是否足以知道Backbone是否会对此感到满意。< / p>

  3. jsdom中运行基于Backbone的代码。 Jsdom提供逼真的document和{{1}},就像您的代码在浏览器中运行一样,但它有其局限性。我不知道Backbone是否会对这些限制感到满意。

答案 1 :(得分:3)

另一种解决方案是使用https://www.npmjs.com/package/window-or-global

import React, { Component } from 'react'
// in node, you'll get the global object instead of crashing by an error 
import root from 'window-or-global'

class MyComponent extends Component {

  // this method is only invoked in the browser environment 
  componentDidMount() {
    root.addEventListener(/*...*/)
  }

  componentWillUnmount() {
    root.addEventListener(/*...*/)
  }

  render() {}

}

// Voilà. Enjoy your universal react component! ;) 
// No more 'window is not defined' errors when you render your component 
// on server side. 

要安装,请运行npm install --save window-or-global

在服务器上运行测试(例如使用mocha-webpack)比在浏览器中运行更快。