web-dev-qa-db-ja.com

ノードからのモカjsのグローバルウィンドウ変数の操作

私はjsユニットテストに不慣れで、バックボーンコンタクトマネージャーのチュートリアルにモカを使用しようとしています this github repo にあります。ただし、最初にグローバルwindow.ContactManager変数が存在するかどうかをテストし、後でstart関数内の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;
    })
});

コンソールでテストを実行してモカに存在するグローバルウィンドウ変数をテストしてアクセスするにはどうすればよいですか?

13
ivan

ブラウザでJavaScriptコードを実行することと、ノードでJavaScriptコードを実行することの違いを無視しています。

ブラウザでは、window名は、すべてのグローバル変数を保持するオブジェクトへの参照です。したがって、最も外側のスコープでfoo = 1を実行すると、グローバルfooを宣言します。これは、window.fooとしてもアクセスできます。逆に、window.bar = 1のような新しいフィールドを割り当てると、barという新しいグローバルが作成されます。

Nodeでは、グローバルオブジェクトはglobalとしてアクセスされます。したがって、最も外側のスコープでfoo = 1を実行すると、fooglobal.fooとしてアクセスできます。そして、global.bar = 1を実行すると、barという名前の新しいグローバルがあります。

コードは、グローバルオブジェクトへの参照ではないように見えるwindowオブジェクトを変更することを示しています。オプション:

  1. NodeではなくブラウザでMochaを実行します。 Mochaのドキュメント を参照してください。

  2. Node環境を設定して、ノードを満たすのに十分なブラウザ環境を模倣します。グローバルwindow変数をglobalmightで十分ですが、Backboneがこれで満足できるかどうかを知るのに十分なバックボーンは知りません。

  3. jsdom でバックボーンベースのコードを実行します。 Jsdomは、コードがブラウザーで実行されているかのように、現実的なwindowおよびdocumentを提供しますが、制限があります。バックボーンがこれらの制限に満足するかどうかはわかりません。

13
Louis

別の解決策は 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 を使用して)、ブラウザーよりもはるかに高速になります。

4
Ser