Ember.js 中的路由采用什么样的单元测试解决方案? [关闭]

2024-02-18

我正在寻找在 Ember.js 应用程序中对路由进行单元测试的最佳解决方案。我找到了两种解决方案,我希望你告诉我什么是最适合你的。 这两个实现可以在这里找到:http://jsbin.com/URaKULa/1/edit http://jsbin.com/URaKULa/1/edit

//=====================================
// Source :
//=====================================

App = Em.Application.create({
});

App.UserEditRoute = Ember.Route.extend({
    model: function () {
        // here we tell the route to use its parent model 
        return this.modelFor('user');
    },
    activate: function () {
        this.controllerFor('user').set('editMode', true);
    },
    deactivate: function () {
        this.controllerFor('user').set('editMode', false);
    },
    events: {
        goBack: function () {
            this.transitionTo('user');
        }
    }
});

// defer readiness and set location's router to none in order to stop main application initialization
App.setupForTesting();

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

//=====================================
// Test :
//=====================================

//-----------------
// First solution
//-----------------
(function () {
    var originalTemplates;
    var container;
    var Router;
    var router;

    function bootTestApplication() {
        router = container.lookup('router:main');
        Ember.run(TestApp, 'advanceReadiness');
    }

    function handleURL(path) {
        return Ember.run(function () {
            return router.handleURL(path).then(function (value) {
                ok(true, 'url: `' + path + '` was handled');
                return value;
            }, function (reason) {
                ok(false, 'failed to visit:`' + path + '` reason: `' + reason);
                throw reason;
            });
        });
    }


    module('First solution for test routes', {
        setup: function () {
            Em.run(function () {

                // We create a fake test Application to isalate route
                TestApp = Em.Application.create({
                    LOG_TRANSITIONS: true,
                    name: "TestApp",
                    rootElement: "#qunit-fixture"
                });
                // We defer initialization and disabled location
                TestApp.setupForTesting();

                // Save the router
                Router = TestApp.Router;

                // Save a loading route just in case
                TestApp.LoadingRoute = Ember.Route.extend({
                });

                // Save the global TestContainer to lookup  what you want
                container = TestApp.__container__;

                // We save the current ember templates to not impact the other unit test
                // when we will overide a few.
                originalTemplates = Ember.$.extend({}, Ember.TEMPLATES);

                // Override/mock application test for isolation
                Ember.TEMPLATES.application = Ember.Handlebars.compile("{{outlet}}");

                // You can here overide other templates if necessary
            });
        },
        teardown: function () {
            Ember.run(function () {
                // deleting the Test application
                TestApp.destroy();
                TestApp = null;
                // reset old Ember templates
                Ember.TEMPLATES = originalTemplates;
            });
        }
    });

    test('UserEditRoute', function () {
        Router.map(function () {
            this.resource('user', function () {
                this.route('edit');
            });
        });

        // Save the App.UserEditRoute to test into the isolated context
        TestApp.UserEditRoute = App.UserEditRoute;

        // we define a fake UserRoute who will return the expected model of the UserEditRoute
        var expectedUserModel = Em.Object.create({name: 'Model from user route'});
        TestApp.UserRoute = Em.Route.extend({
            model: function () {
                return expectedUserModel;
            }
        });

        // Mock of UserController and UserEditController classes
        TestApp.UserController = Em.Controller.extend({
            editMode: false
        });

        TestApp.UserEditController = Em.Controller;

        // We define an empty template
        Ember.TEMPLATES['user/edit'] = Ember.Handlebars.compile("");

        // Start TestApp application
        bootTestApplication();

        // retrieve UserController instance
        var userCtrl = container.lookup('controller:user');
        var userEditCtrl = container.lookup('controller:userEdit');

        handleURL('/user/edit');
        // assert activate hook behavior and model
        ok(userCtrl.get('editMode'));
        ok(userEditCtrl.get('content', expectedUserModel));

        // reset tested properties
        userCtrl.setProperties({
            editMode: true,
            content: null
        });

        handleURL('/');
        // assert deactivate hook behavior
        ok(!userCtrl.get('editMode'));

        // here we place other test like event handling, or to test others route's hooks
    });
})();


//-----------------
// Second solution
//-----------------
(function(){
  module('Second solution to test routes',{
    setup:function(){
    },
    teardown:function(){
    }
  });

  test('UserEditRoute',function(){
    var container = new Em.Container();
    var expectedUserModel = Em.Object.create({name: 'Model from user route'});

    container.register("controller:user", Em.Controller.extend({
      editMode: false
    }));
    container.register("route:user", Em.Route.extend({
      currentModel:expectedUserModel
    }));

    var userEditRoute = App.UserEditRoute.create({
      router : {
        container:container,
        router:{}
      },
      container:container
    });

    var userCtrl = container.lookup('controller:user');

    equal (userEditRoute.model(), expectedUserModel);
    userEditRoute.activate();
    equal (userCtrl.get('editMode'), true);
    userEditRoute.deactivate();
    equal (userCtrl.get('editMode'), false);
  });
})();

第一个解决方案是基于单元测试的Ember.js团队(更多详细信息,请参见这里https://github.com/emberjs/ember.js/blob/master/packages/ember/tests/routing/basic_test.js https://github.com/emberjs/ember.js/blob/master/packages/ember/tests/routing/basic_test.js)这种方法的优点是您可以测试路由的全局行为,而不是测试每个钩子。例如,如果我将“editMode”集移动到另一个钩子(如“setupController”)中,测试将继续通过并且正常。 此外,通过这种方式,我可以通过在“用户/编辑”模板中添加操作来测试事件处理。

这种方法的最大缺点是非常无聊,我们要测试的代码比实现多四倍......

第二种解决方案更轻量、更优雅,但灵活性较差。我们使用的容器类允许大量依赖项注入,并允许模拟所有连接的类,例如 UserRoute 或 UserController。这种方法要求您模拟 Emberjs 内部路由使用的所有必要属性和方法(例如路由器)。

那么你最喜欢什么?或者你还有另外一个吗?


None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Ember.js 中的路由采用什么样的单元测试解决方案? [关闭] 的相关文章

随机推荐

  • android中进程的内存信息

    我正在尝试计算 android 中单个进程使用的内存 因为我陷入了这一点 ActivityManager am ActivityManager getSystemService Context ACTIVITY SERVICE androi
  • 无法使用 WAMP 访问 localhost 或 phpMyAdmin

    我正在运行 Apache v2 2 21 PHP v5 38 和 MySQL v5 5 16 WAMP 图标为绿色 正如帖子标题所述 我无法从 WAMP 系统托盘图标菜单访问 localhost 或 phpMyAdmin 也无法通过键入ht
  • 如何给透明的UIView添加阴影?

    我怎样才能重现这种阴影 我的问题是 如果我使用高 alpha 颜色或clearColor 则没有投影 如果我使用低 alpha 颜色 则看不到板下的投影 随着音量的变化 彩色部分 阴影也在移动 所以它不是纯粹的 Photoshop 尝试使用
  • 以编程方式为 Jetty 9 嵌入式配置 SSL

    我正在使用 jetty 版本 9 0 0 M4 并尝试将其配置为接受 SSL 连接 按照以下说明进行操作 http www eclipse org jetty documentation current configuring connec
  • 使用 apache commons 配置 XMLConfiguration 格式化 XML 输出

    我正在使用 apache commons 配置 XMLConfiguration 来构建和保存 XML 文件 保存的时候没有格式化 我得到类似的东西
  • Scapy发送的数据包收不到

    我正在尝试使用以下命令使用 scapy 发送 UDP 数据包 gt gt send IP dst 127 0 0 1 src 111 111 111 111 UDP dport 5005 Hello Sent 1 packets 并从tcp
  • Django Queryset:在过滤之前在 SQL 中转换 VARCHAR 字段

    我有一个我无法控制的表 但需要从中进行选择 字段 building 是一个 varchar 并且在我的 非托管 django 模型中也是这样定义的 但从该表中进行选择时 应将其视为整数 有 000100 之类的值 甚至末尾有空格 我需要一个
  • boost 属性树 put/get DBL_MAX

    我正在编写一个 ptree 在某些时候我需要放入 DBL MAX 作为默认值 当我打开生成的 xml 文件时 我看到了正确的数字 但是当我使用 ptree get 获取数字时 会引发异常 conversion of data to type
  • php imagick,如何使区域透明

    我想使 Imagick 对象内的一个区域透明 具有特定的宽度 高度和顶部位置 例如 我需要一个从第 15 像素到顶部 30 像素 x 30 像素的透明区域 但我找不到方法来实现 canvas1 new Imagick canvas1 gt
  • 如何检查内核中SMP是否启用或禁用?

    我想知道如何检查我正在运行的机器 内核是否配置为 SMP 当然 我可以查看内核 config文件并可以搜索它 但是 问题是假设我没有源代码 我将如何检查 SMP 配置 有没有proc文件来检查吗 下面说我没有多核 cat proc cpui
  • MPI_Send 和 MPI_Recv 的行为

    为什么要写这几行代码 if my rank 0 sprintf msg Hello from d of d my rank comm sz if my rank 2 sleep 2 sprintf msg Hello from d of d
  • 如何使用 Win2D 模拟 DeviceLost 事件?

    我有一个CanvasControl在 UWP 应用程序中 我注意到当我将 Surface 单独放置一段时间并且它会自动进入睡眠状态时 CanvasControl恢复后不再起作用 之前绘制的位图现在是空白的 我尝试在 Visual Studi
  • 失败后自动重新部署

    我使用 VSTS 在每次提交到特定分支后自动发布我的应用程序 任务基本上是 重新创建数据库 如果第一个没问题 gt 部署 API 和 Web 如果第二个没问题 gt 部署并重新启动一些 Windows 服务 在第二步中 有时会由于某些连接或
  • Couchbase 文档 ID 生成

    我有一个与 couchbase 6 0 集成的 Springboot 应用程序 我读过 如果一个键用 Id 注释 那么它将保存为文档 ID 并且不会成为 json 的一部分 然后我在键上一起使用了 Id和 Field 但该字段仍然没有出现在
  • 如何在 Jupyter / IPython 中覆盖之前的打印行

    我完全清楚print Blah end r 但这在 Jupyter IPython 笔记本中不起作用 因为它在终端中通常不打印任何内容 或者如果操作非常快 则会触发异常 难道这就是不可能吗 谢谢 None
  • 单独读取数据 fscanf

    我正在尝试从文件中读取数字 该文件具有以下格式 2 4 5 7 3 2 4 7 我尝试使用fscanf收集直到换行符的所有数字并将数字存储在数组中 与第二行相同 但直接从第二行开始不会再次开始并将其存储在另一个数组中 是否可以使用以下方法来
  • 如何修复错误:此类与键 tableView 的键值编码不兼容。 [复制]

    这个问题在这里已经有答案了 我做了一个应用程序Table View and Segmented Control 这是我第一次 我正在使用一些代码和一些教程 但它不起作用 当我运行我的应用程序时 它崩溃了 并在日志中显示此错误 MyAppli
  • 在 shell/bash 中的两个命令之间连接输入和输出

    我有两个 UNIX 程序 A 和 B 它们从 stdin stdout 读取和写入 我的第一个问题是如何将 A 的 stdout 连接到 B 的 stdinandB 的标准输出到 A 的标准输入 即 类似 A B而是双向管道 我怀疑我可以通
  • 为什么我的库无法在 CocoaPods 网站上扩展?

    我正在尝试通过 CocoaPods 网站访问我的图书馆信息 但无法访问 所有其他库似乎都能够扩展 我的是 MKWeatherUndergroundKit 这是我的 podspec Pod Spec new do s s name MKWea
  • Ember.js 中的路由采用什么样的单元测试解决方案? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我正在寻找在 Ember js 应用程序中对路由进行单元测试的最佳解决方案 我找到了两种解决方案 我希望你告诉我什么是最适合你的 这两个实现可以