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

时间:2017-01-02 13:58:35

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

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

我的控制器看起来像这样:

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

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

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

2 个答案:

答案 0 :(得分:2)

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

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

请看the sample twiddle

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

答案 1 :(得分: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');
});