【问题标题】:How to unit test an ember controller如何对 ember 控制器进行单元测试
【发布时间】:2017-01-02 13:58:34
【问题描述】:

我在 ember 控制器中定义了一个动作,该动作调用了作为控制器一部分的 2 个独立函数。我想在单元测试中模拟这些函数,以确认操作方法是否调用了正确的函数。

我的控制器如下所示:

export default Ember.Controller.extend({
    functionA() {
        return;
    },
    functionB() {
        return;
    },
    actions: {
        actionMethod(param) {
            if(param) {
                return this.functionA();
            }
            else {
                return this.functionB();
            }
         }
    }
});

实际上,控制器可以工作,但是在单元测试中,functionA 和 functionB 都是未定义的。我试图将this 记录到控制台,但找不到functionA 和functionB 的位置,所以我无法正确模拟它们。我希望它们位于操作旁边的对象的顶层,但我只发现 _actionsactionMethod 正确定义。

我的单元测试如下所示

const functionA = function() { return; }
const functionB = function() { return; }
test('it can do something', function(assert) {
    let controller = this.subject();
    // I don't want the real functions to run 
    controller.set('functionA', functionA);
    controller.set('functionB', functionB);
    controller.send('actionMethod', '');
    // raises TypeError: this.functionA is not a function

    // this doesn't work etiher
    // controller.functionB = functionB;
    // controller.functionA = functionA;
    // controller.actions.actionMethod();
}

有人对我如何在测试环境中替换这些功能有任何想法吗?或者,是否有更好的方法来测试此功能或设置我的控制器?

  • 编辑 错字:this.subject to this.subject()

【问题讨论】:

  • 旁注:1.要创建控制器对象,您需要调用this.subject()。 2.controller.send方法不会向调用者返回任何值
  • 哎呀错字-我打电话给this.subject()。至于controller.send,我尝试了如上所示的方法以及调用controller.actions.actionMethod()

标签: unit-testing ember.js ember-testing


【解决方案1】:

要替换unit测试中控制器的功能,可以将参数传递给this.subject()函数:

 let controller = this.subject({
     functionA(){
         //this function overriddes functionA
     },
     functionB(){
         //this function overriddes functionB
     },
 });

the sample twiddle

这种方法对于替换控制器注入的service特别有用。

【讨论】:

    【解决方案2】:

    介绍你正在处理的对应属性,比如说name属性, 所以你的控制器看起来像这样,

    import Ember from 'ember';
    export default Ember.Controller.extend({
      name:'',
      functionA() {
            this.set('name','A');
        },
        functionB() {
            this.set('name','B');
        },
        actions: {
            actionMethod(param) {
                if(param) {
                    return this.functionA();
                }
                else {
                    return this.functionB();
                }
             }
        }
    });
    

    您可以在调用actionMethod 后测试name 属性值。

    test(" testing functionA has been called or not", function(assert){
      let controller = this.subject();
      controller.send('actionMethod',true);
      //If you would like to call functionA just say  controller.functionA()
      assert.strictEqual(controller.get('name'),'A',' name property has A if actionMethod arguments true');
      controller.send('actionMethod',false);
      assert.strictEqual(controller.get('name'),'B',' name property has B actionMethod arguments false');
    });
    

    【讨论】:

    • 我只是想回答你的问题来了解自己,坦率地说,我没有在我的项目中编写任何测试
    • 如果您想在创建对象时动态定义属性,那么您需要将其作为参数传递给 subject 方法,就像我们使用 create() 创建对象时所做的那样。 this.subject({functionA:function(){this.set('name','AA'); return ;}});
    猜你喜欢
    • 2012-04-24
    • 2018-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-31
    • 1970-01-01
    • 1970-01-01
    • 2011-07-26
    相关资源
    最近更新 更多