【问题标题】:Front end javascript testing using Require and Resharper使用 Require 和 Resharper 进行前端 javascript 测试
【发布时间】:2015-02-26 13:13:16
【问题描述】:

所以我一直试图弄清楚前端测试是如何工作的(单元测试),但我在某个点上卡住了。

所以我的茉莉花测试设置如下:

describe('Blabla', function () {

    it('returns true', function () {
        var people = require(["people"], function(ppl) {
            return ppl;
        });
        expect(people.getTitle()).toBe('People piolmjage');
    });
});

但是运行这个让我:

TypeError: undefined is not a function

很明显,人是不确定的。所以也许我的回调来得太晚了。但是,如果我删除回调,我会收到以下错误:

it('returns true', function () {
    var people = require("people");
    expect(people.getTitle()).toBe('People piolmjage');
});

错误:尚未为上下文加载模块名称“people”:_。使用 require([])

我认为我的设置有问题...有人知道如何让这个 FE 测试工作吗?

我确实设法让它从控制台工作并使用 define 结合 phantomjs 和 durandal 测试文件,但我需要它在控制台之外工作,因此我不能使用这个 define 因为测试运行器赢了找不到我的测试。

这就是为什么我需要使用 CommonJS 来获取所需的视图模型。

人物模型

define([],
function () {
    var getTitle = function() {
        return "hello";
    }

    var peopleViewModel = {
        title: 'People page',
        getTitle: getTitle
    };
    return peopleViewModel;
});

更新

我得到了代码,但 没有 使用 resharper。关注this page from the durandal webpage

但这让我得到控制台输出,这是一种非结构化的方式来实际阅读。

但是,我可以使用 define 关键字,然后它就可以正常工作了。所以我认为是 require 关键字让我搞砸了?

更新 2

所以我用 fiddler 来检查发生了什么。我也终于让它工作了(有点......)。

我的测试文件现在看起来像这样:

///<reference path="../../Scripts/require.js"/>
///<reference path="../../test/lib/jasmine-2.1.3/jasmine.js"/>

///<reference path="../../App/viewmodels/people.js"/>

describe('Blabla', function () {
    it('require test', function (done) {
        require(['people'], function (people) {
            expect(people.title).toBe('People page');
            done();
        });
    });
});

然后我更改了我的people 文件:

define("people", ["bla"], function (bla) {
    return {
        title: 'People page',
        bla: bla
    };
});

正如您在此处看到的,我将我的视图模型命名people。 这适用于测试运行者,但他实际上并没有通过 requireJS 获得任何文件,而只有参考路径。这也不符合我的需求,因为 durandal 模型未命名

提琴手截图:

所以基本上他不使用 requireJS 来获取视图模型,因此我不能只使用 require.config 初始化程序来获取我的 viewmodels 文件夹并使用 requireJS 下载每个视图模型。有什么想法吗?

【问题讨论】:

    标签: javascript unit-testing requirejs frontend durandal


    【解决方案1】:

    我终于搞定了,花了我一天半的时间。

    无论如何,我不再使用 resharper,或者更准确地说是测试运行器。 Chutzpah 是我最后求助的那个。这也让我进行了一些研究,但我得到了它包含我想要的所有内容的地步。

    Check this post for sure

    这是我所做的:

    我的 people.js 看起来像这样:

    define(['viewmodels/bla'], function (bla) {
        return {
            title: 'People page',
            bla: bla //testing dependencies on other viewmodels
        };
    });
    

    然后我也做了一个bla.js

    define(function() {
        return {
           bla: "bla"
        };
    });
    

    现在开始测试:

    describe('Blabla', function () {
    it('require test', function (done) {
        require(['viewmodels/people'], function (people) {
            expect(people.title).toBe('People page');
            done();
        });
    });
    
    it('dependency on require test', function (done) {
        require(['viewmodels/people'], function (people) {
            console.log(people.bla);
            expect(people.bla.bla).toBe('bla');
            done();
        });
    });
    });
    

    然后最终,阅读顶部提供的链接上的答案,我不得不创建一个 Chutzpah 配置文件来创建测试工具

    {
       "Framework": "jasmine",
       "TestHarnessReferenceMode": "AMD",
       "TestHarnessLocationMode": "SettingsFileAdjacent",
       "References" : [
           {"Path" : "../Scripts/require.js" }, 
           {"Path" : "requireConfig.js" }
       ],
       "Tests" : [
         {"Path": "specs"}
       ]
    }
    

    现在,使用 Visual Studio 测试运行器 运行测试实际上得到了我需要的一切,如您所见,我现在可以像这样通过 require 访问我的所有 viewmodelsrequire(['viewmodels/whateverviewmodel'], function(whateverviewmodel){....})

    我希望这个答案可以让人们使用 Jasmine 和 RequireJS 测试您的 (Durandal)SPA。

    我知道我在这个答案中的视图模型,也不在问题本身中,说了很多,但这应该让你知道如何去做这一切。

    小编辑

    您现在还可以在测试中使用 require([]... 跳过回调混乱,并像使用 define 构建您的视图模型一样构建您的测试

    define(['viewmodels/people'], function (people) {
        describe('Blabla', function () {
            it('require test', function () {
                expect(people.title).toBe('People page');
            });
    
            it('dependency on require test', function () {
                console.log(people.bla);
                expect(people.bla.bla).toBe('bla');
            });
        });
    });
    

    这样可以减少缩进,并且本身更具可读性。

    【讨论】:

      【解决方案2】:

      RequireJS 提供的require 调用固有是异步的,所以你需要做这样的事情:

      it('returns true', function (done) {
          require(["people"], function(people) {
              expect(people.getTitle()).toBe('People piolmjage');
      
              done(); // Signal that the test is done.
          });
      });
      

      您在问题中显示的第一次尝试无效。这是经典的“尝试从异步代码中同步返回值”的错误。使用require("people") 的第二次尝试也不起作用,因为此require 调用是伪同步的,并且仅当请求的模块已经加载时才会起作用。有关此伪同步 require 工作原理的说明,请参阅 this answer

      【讨论】:

      • 在您的示例中,我仍然收到 people 未定义的错误。 错误:超时 - 在 jasmine.DEFAULT_TIMEOUT_INTERVAL 指定的超时内未调用异步回调。 并在控制台中显示:getTitle() of undefined
      • 你的模块真的返回了有用的值吗?您没有在问题中显示您的模块代码。
      • 只要 RequireJS 配置为在需要 "people" 时加载您在问题中显示的代码(而不是其他东西),那么它应该可以工作。另外,您是否复制并粘贴了我在答案中输入的内容?尝试编辑您的原始代码以复制我在答案中的内容很容易出错。
      • 我确实编辑了我的原始代码但没有成功...我似乎无法找出他为什么没有正确包含“人”模型µ
      猜你喜欢
      • 1970-01-01
      • 2013-07-11
      • 1970-01-01
      • 2012-06-28
      • 2015-06-11
      • 1970-01-01
      • 2017-10-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多