如何对 ember 控制器进行单元测试

How to unit test an ember controller

我在 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 的位置,因此我无法正确模拟它们。我希望它们位于动作旁边对象的顶层,但我只发现 _actions 正确定义了 actionMethod

我的单元测试如下所示

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();
}

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

介绍对应的属性你正在打交道,比方说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');
});

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

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

看看the sample twiddle

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