简体   繁体   English

如何在requirejs的测试中注入模块到单元测试应用程序?

[英]How to inject module in test for requirejs to unit test application?

I have two modules, ModuleA and ModuleB.我有两个模块,ModuleA 和 ModuleB。 ModuleB depends on ModuleA. ModuleB 依赖于 ModuleA。 But as far as I know requirejs is kind of service locator.但据我所知,requirejs 是一种服务定位器。 So how do I unit test this kind of pattern in my code.那么我如何在我的代码中对这种模式进行单元测试。

define('moduleA', function() {
    var ModuleA = function() {
        this.doSomething = function() {
            return true;
        }
    }
    return ModuleA;
});

define('moduleB', ['moduleA'], function(ModuleA) {
    var moduleA = new ModuleA();
    var ModuleB = function() {
        this.doSomethingElse = function() {
            if(moduleA.doSomething()) {
                // do something else and return

            } else {
                // do other things and return
            }
        }
    }

    return ModuleB
});

/*Test for moduleB*/
define('test', ['moduleB', function(ModuleB) {
    describe('', function() {
        var moduleB = new ModuleB();
        expect(moduleB.doSomethingElse()).toBe(true);
    });
});

Because ModuleA will be initialised all the time.因为 ModuleA 会一直被初始化。 Is there anyway I could inject some mock to ModuleB and test that?无论如何,我可以向 ModuleB 注入一些模拟并进行测试吗? And I would like to not use singleton because I'm not sure if the test will keep failing because of unforeseen behaviour.而且我不想使用单例,因为我不确定测试是否会因为不可预见的行为而继续失败。

Note: I just type the code so their might be some compilation error.注意:我只是输入代码,所以它们可能是一些编译错误。

This code pattern is not unit testable.此代码模式不可单元测试。 I guess someone could come up with a way of tricking RequireJS to load different module definition and unload it at the end of the test but that would be too complicated and too error prone, and wouldn't solve the problem of bad coding practice.我想有人可以想出一种方法来欺骗 RequireJS 加载不同的模块定义并在测试结束时卸载它,但这太复杂且太容易出错,并且无法解决糟糕的编码实践问题。

The pattern is not testable because inside of moduleB definition you are creating new instance of moduleA (plus loading of ModuleA is "hardcoded").该模式不可测试,因为在 moduleB 定义内部,您正在创建 moduleA 的新实例(加上 ModuleA 的加载是“硬编码”)。 To make it testable you need to inject it.要使其可测试,您需要注入它。 Consider something like:考虑这样的事情:

define('moduleB', function() {
    var ModuleB = function(moduleA) {
        this.__moduleA = moduleA;
        this.doSomethingElse = function() {
            if(this.__moduleA.doSomething()) {
                // do something else and return

            } else {
                // do other things and return
            }
        }
    }

    return ModuleB
});

To further explore this small refactoring I would suggest reading about "dependency injection".为了进一步探索这个小重构,我建议阅读“依赖注入”。 Skip DI tools like Guice, just get to the core of DI idea.跳过像Guice这样的DI工具,直接进入DI思想的核心。

Misko Hevery has couple interesting posts about this kind of OOP patterns including how to deal with "new" keyword: http://misko.hevery.com/2008/09/10/where-have-all-the-new-operators-gone/ Misko Hevery 有几篇关于这种 OOP 模式的有趣帖子,包括如何处理“new”关键字: http : //misko.hevery.com/2008/09/10/where-have-all-the-new-operators-走了/

I can not find it right now, but I believe Misko had nice post about 3 hierarchies in OOP, inheritance hierarchy (most obvious), creation hierarchy (who creates what) and dependency hierarchy (who uses whom).我现在找不到它,但我相信 Misko 有关于 OOP 中的 3 个层次结构的好帖子,继承层次结构(最明显),创建层次结构(谁创建了什么)和依赖层次结构(谁使用谁)。 These 3 hierarchies are completely different.这3个层次是完全不同的。 Usually if class B creates class A it shouldn't use it.通常,如果 B 类创建 A 类,则不应使用它。 The role of class B seems to be of a factory - it creates instances. B 类的角色似乎是一个工厂——它创建实例。 There should be some other class C that is using injected instance of class A to perform some business logic.应该有一些其他类 C 正在使用类 A 的注入实例来执行一些业务逻辑。

As a side note, since you are already using AMD modules and JS "classes" why not to make your classes/object look and behave more like proper OOP classes/object?附带说明一下,既然您已经在使用 AMD 模块和 JS“类”,为什么不让您的类/对象看起来和行为更像正确的 OOP 类/对象? Dejavu can help you with that: http://wojciechszela.com/blog/2014/01/13/object-oriented-programming-in-javascript/ Dejavu 可以帮助您: http : //wojciechszela.com/blog/2014/01/13/object-oriented-programming-in-javascript/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM