Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/455.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在单元测试之间重置requirejs模块_Javascript_Unit Testing_Requirejs_Karma Runner - Fatal编程技术网

Javascript 如何在单元测试之间重置requirejs模块

Javascript 如何在单元测试之间重置requirejs模块,javascript,unit-testing,requirejs,karma-runner,Javascript,Unit Testing,Requirejs,Karma Runner,我有一个JavaScript项目,我想观察TDD方法。为此,我选择了karma框架和requirejs库,并遵循karma文档中演示的示例 有一个单元测试文件的示例,它是: define(['app', 'jquery', 'underscore'], function(App, $, _) { describe('just checking', function() { it('works for app', function() { var

我有一个JavaScript项目,我想观察TDD方法。为此,我选择了karma框架和requirejs库,并遵循karma文档中演示的示例

有一个单元测试文件的示例,它是:

define(['app', 'jquery', 'underscore'], function(App, $, _) {

    describe('just checking', function() {

        it('works for app', function() {
            var el = $('<div></div>');

            var app = new App(el);
            app.render();

            expect(el.text()).toEqual('require.js up and running');
        });

        it('works for underscore', function() {
            // just checking that _ works
            expect(_.size([1,2,3])).toEqual(3);
        });

    });

});
define(['app','jquery','下划线'],函数(app,$,\ux){
描述('只是检查',函数(){
它('适用于应用程序',函数(){
变量el=$('');
var应用=新应用(el);
app.render();
expect(el.text()).toEqual('require.js启动并运行');
});
它('用于下划线',函数(){
//只是检查一下是否有效
期望(u.size([1,2,3])).toEqual(3);
});
});
});
这种方法的主要问题是无法为每个测试清除应用程序模块。因此,如果在一个
it
调用中应用程序中有一些更改(如关闭变量更改等),那么它们可能会影响其他
it
调用

有人能提出一些建议吗?这些是如此流行的工具,我不敢相信没有人遇到过这样的情况

因此,为了重述这个问题,我想问一下这些更具体的问题的答案:

  • 有没有办法在requirejs中“重置”(清除)模块?(事实上,我想除了再次重新加载所有模块之外,没有其他方法了。
  • 有没有更好的方法来运行karma和requirejs,这样模块就不会有其他测试(
    it
    function calls)的任何残余(副作用)
  • 有没有办法在requirejs中“重置”(清除)模块
您可以使用,但文档中提到了一些问题。据我所知,没有任何调用可以用来表示“卸载此模块及其依赖的所有内容”,这在复杂的应用程序中可能是必需的

  • 有没有更好的方法来运行karma和requirejs,这样模块就不会受到其他测试(it函数调用)的任何影响(副作用)

更好的方法是设计应用程序,使状态绑定到实例化的对象,而不是模块本身。这就是我在测试套件中为我的一个大型应用程序所做的。beforeach钩子重置需要重置的内容,并为每个测试重新实例化应用程序。

在谷歌的帮助下,我找到了一个解决方案。我不能说它是理想的,但它至少可以工作,并且在每个测试中,所需的模块都处于原始状态

首先,需要有这样的
main.js
测试文件,它与中几乎相同,只是测试没有定义为模块,也没有包含为依赖项:

require.config({file
    baseUrl: '/base',
    paths: {},
    shim: {},
    deps: [],
    callback: window.__karma__.start
});
在主业力形态中,这必须存在(你需要调整自己的路径)

在测试本身中,我们利用jasmine async测试功能和requirejs.unde方法“清除”模块(这将重置加载程序的内部状态,以忘记模块的先前定义,如中所述)

此方法有一个含义,即它不会重置其他模块,这些模块已经加载并依赖于重置模块,但如果一个人以正确的方式编写测试,也就是说他只测试一个模块(可能是一些父模块,子模块从中继承了一些行为),则这不应该是一个问题,因此,一次定义多个模块应该不难

describe('Some/Module tests', function() {
    'use strict'
    var M

    beforeEach(function(done) {
        requirejs.undef('src/Some/GParentModule')
        requirejs.undef('src/Some/ParentModule')
        requirejs.undef('src/Some/Module')
        require(['src/Some/Module'], function(m) {
            M = m
            done()
        })
    })

    it('some description', function() {
        var i = 0

        for (var prop in M) {
            i++
        }
        expect(i).toEqual(1)
        expect(prop).toEqual('init')
        expect(M.init).toEqual(jasmine.any(Function))
    })
})
我已经检查过了,在
it
调用之间,对模块的更改不会持久,所以我认为,使用这种方法是安全的


谢谢大家的帮助,如果有人有更好的方法,请在这里回答。

谢谢,但我不能同意您的建议,即设计应用程序,使状态绑定到您实例化的对象,而不是模块本身,因为即使我这样做(尽管我不想这样做),问题仍然存在,至少在JavaScript中是这样。由于模块定义是一个函数这一事实,即使我实例化了一个对象,我也不能在每次测试中都清楚地依赖它(至少可以更改一些闭包变量)。看来我已经找到了一个可接受的解决方案,我将把它作为一个答案发布below@user907860您一定对JavaScript的工作原理有一些误解,因为它是完全可行的。正如我在回答中所说,我已经做到了。你能提供一些代码示例吗?我的意思是,如果您在许多
it
调用中测试的模块只有一个require/define调用,那么您无法确定(只有在您没有侵入模块内部的情况下)它的状态是否已重置。因为,如果我在模块实例上调用一个方法,它是这样的:
define(function(){var foo;return function(){this.method=function(){foo++}}})
。然后,如果我调用
var-ins=new模块;ins.method()
在一个测试中,我将在另一个测试中使用
foo+=1
这个模块。即使在另一个测试中(或在beforeach中),我调用
var ins_2=new module
我仍将使用其内部foo变量递增1的模块
describe('Some/Module tests', function() {
    'use strict'
    var M

    beforeEach(function(done) {
        requirejs.undef('src/Some/GParentModule')
        requirejs.undef('src/Some/ParentModule')
        requirejs.undef('src/Some/Module')
        require(['src/Some/Module'], function(m) {
            M = m
            done()
        })
    })

    it('some description', function() {
        var i = 0

        for (var prop in M) {
            i++
        }
        expect(i).toEqual(1)
        expect(prop).toEqual('init')
        expect(M.init).toEqual(jasmine.any(Function))
    })
})