如何在Mocha测试中要求命名空间模型?

时间:2017-01-25 06:36:49

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

我有一个复杂的结构化骨干应用程序尚未测试。

我选择Mocha + Chai作为测试套件,但在包含一些模块时面临问题。

所有模型都命名为

Model.Service = Backbone.Model.extend({
...
...

Model.Partner = Backbone.Model.extend({
...
...
etc. 

模型名称空间本身声明为

//global_vars.js
var GLOBAL = window;
...
GLOBAL.Model            = {};

当我尝试编写像

这样的简单测试时
'use strict';
require ('mocha');    

var Service =  require ('../../client/model/Service.js')
var expect = require ('chai').expect;

describe('Testing Service model', function(){
        it('should create global variable for Service', function(){
            expect(Service).to.be.exist;
        });
    });

它扔错了,

Model.Service = Backbone.Model.extend({
^

ReferenceError: Model is not defined

添加,

require('../../client/global_vars.js');

Service声明之前,但这次是

var GLOBAL = window;
             ^

ReferenceError: window is not defined

我实际上并不熟悉javascript mvc结构,节点模块包含等等,真的不知道如何挖掘。

目录结构(如果需要)

$ tree source/client/
source/client/
├── Application.js 
├── collection
│   ├── I18n.js
│   ├── Invoice.js
│   └── Service.js
├── controller
│   ├── hardware
│   │   └── Cash.js
│   ├── Hardware.js
│   ├── I18n.js
│   ├── Remote.js
│   └── ServiceManager.js
├── draft.js
├── global_vars.js
├── lib
│   ├── access_deep_object.js
│   ├── backbone.validation.async.js
│   ├── color_transition.js
│   ├── dom_utils.js
│   ├── error.js
│   ├── jquery.form.serialize_object.js
│   ├── number_utils.js
│   ├── path.js
│   ├── promise_core.js
│   ├── remove_regexp_specials.js
│   ├── stringTemplate.js
│   ├── string_utils.js
│   └── the_key.js
├── model
│   ├── Cacheable.js
│   ├── Controller.js
│   ├── Countdown.js
│   ├── Device.js
│   ├── hardware
│   │   ├── BillAcceptor.js
│   │   ├── CashDispenser.js
│   │   ├── IDReader.js
│   │   ├── SmartCoin.js
│   │   └── ThermalPrinter.js
│   ├── I18n.js
│   ├── Invoice.js
│   ├── Object.js
│   ├── Partner.js
│   ├── Performer.js
│   ├── ServerSideEvent.js
│   ├── Service.js
│   ├── Session.js
│   ├── Storage.js
│   └── Transaction.js
├── start.js
├── template
................ 
├── vars.js
├── vendor
................
└── view
    ├── AppView.js
    ├── Console.js
    ├── ModalWindow.js
    ├── page
    │   ├── about.js
    │   ├── articles
    │   │   ├── list.js
    │   │   └── tiles.js
    │   ├── checkout
    │   │   ├── card.js
    │   │   └── cash.js
    │   ├── custom
    │   │   └── mobile_operator
    │   │       ├── auth.js
    │   │       └── packages.js
    │   ├── exception
    │   │   ├── connection.js
    │   │   ├── dataloss.js
    │   │   ├── emergency.js
    │   │   └── transaction.js
    │   ├── gallery.js
    │   ├── input
    │   │   ├── phone.js
    │   │   └── text.js
    │   ├── select
    │   │   └── packages.js
    │   ├── single_invoice.js
    │   ├── start.js
    │   ├── test
    │   │   ├── hardware.js
    │   │   └── payment.js
    │   └── thankyou.js
    ├── Page.js
    ├── Prototype.js
    └── Registration.js

50 directories, 127 files

2 个答案:

答案 0 :(得分:1)

您遇到的问题是,您尝试在没有名为window的全局空间的环境中运行需要将全局空间命名为window的代码。在Node中,全局空间为global。至少你需要这样的东西:

var GLOBAL =  typeof window !== "undefined" ? window : global;

我会将整个shebang放在IIFE中。否则,您将在任何存在的全局空间上定义名为GLOBAL的变量。所以:

(function () {
  var GLOBAL =  typeof window !== "undefined" ? window : global;
  GLOBAL.Model = {};
  // etc...
}());

这将解决您的直接障碍。这就是说,根据您运行的测试类型,您可能需要window尽可能接近实际的DOM Window对象。如果是这样,您可以使用JSDom。有关如何在SO上使用它的问题有很多。多年来我一直在进行数以千计的测试,我的建议是只在你绝对需要的时候使用JSDom。不要误解我的意思,JSDom很棒,对于某些测试来说绝对必要,但它有开销。

答案 1 :(得分:0)

您是否正确设置了测试环境?我的测试有一个单独的目录:

├── Test
|    ├── js
|    |    ├── spec
|    |       ├── myModel.spec.js
|    ├── test.html

然后,在test.html中,包含依赖项

  ...
  <head>
      <meta charset="utf-8">
      <meta name="description" content="">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <link rel="author" href="humans.txt">
      <link rel="stylesheet" href="../node_modules/mocha/mocha.css" />
  </head>
  <body>
      <div id="mocha"></div>
      <!-- JavaScript Test Libraries -->
      <script src="../node_modules/mocha/mocha.js"></script>
      <script src="../node_modules/chai/chai.js"></script>
      <script src="../node_modules/sinon/lib/sinon.js"></script>
      <!-- JavaScript Core Libraries -->
      <script src="../node_modules/underscore/underscore-min.js"></script>
      <script src="../node_modules/jquery/dist/jquery.min.js"></script>
      <script src="../node_modules/backbone/backbone-min.js"></script>
      <!-- JavaScript Application Libraries -->
      <script src="../app/js/namespace.js"></script>
      <script src="../app/js/templates/templates.js"></script>
      <script src="../app/js/models/myModel.js"></script>
      <script src="../app/js/views/myView.js"></script>
      <!-- set up mocha and chai -->
      <script>
          var expect = chai.expect;
          mocha.setup('bdd');

          window.onload = function(){
              mocha.run();
          };
      </script>

      <!-- include our specs -->
      <script type="text/javascript" src="js/spec/namespace.spec.js"></script>
      <script type="text/javascript" src="js/spec/myModel.spec.js"></script>
      <script type="text/javascript" src="js/spec/myView.spec.js"></script>

...
<div id="mocha"></div>
<div id="fixtures" style="display: none; visibility: hidden;"></div>

然后你在[yourModel] .spec.js文件中编写你的测试。在这个例子中,它是myModel.spec.js

describe("App.Models.Station", function () {
    it("Model creation is OK", function () {
        var model = new App.Models.Station();
        expect(model).to.be.ok;
    });
});

然后打开浏览器并打开test.html运行测试。还要检查所有相对路径是否正确。