1

我在 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()
4

2 回答 2

2

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

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

看看样本旋转

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

于 2017-01-03T09:02:31.587 回答
1

介绍你正在处理的相应属性,让我们说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();
            }
         }
    }
});

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

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');
});
于 2017-01-02T15:07:07.840 回答