如何在AngularJS中使用回调对控制器进行单元测试

时间:2015-07-03 23:10:32

标签: javascript angularjs unit-testing callback

我有一个内置回调的控制器:

angular.module('controllers').controller('MainCtrl', function() {
var result = {};
var self = this;
this.test = function(data) {
        jsonld.expand(data, function(err, expanded) {
            self.result = expanded;
        });
    }
});

我的问题是我需要检查"结果"的值。在单元测试中,但如果我只调用ctrl.test(data)然后调用ctrl.result,则ctrl.result的值为{},它应该是测试函数返回的内容(在jsonld.expand中)。有没有办法测试这种行为(在回调发生时测试self.result)?

我已经搜索过,但我发现的所有内容都与自定义服务有关,但在这种情况下,这是一个external library

1 个答案:

答案 0 :(得分:0)

如果要测试代码,则必须遵守某些规则。例如,不要使用全局变量/依赖项。

在您的示例中是jsonld全局依赖。在单元测试中,我们只测试一个组件,依赖项被模拟替换。

如何修改代码以使其更易于测试?

angular.module('controllers')
  .controller('MainCtrl', function(jsonld) {
    var result = {};
    var self = this;
    this.test = function(data) {
      jsonld.expand(data, function(err, expanded) {
        self.result = expanded;
    });
  }
});

唯一的区别是在控制器构造函数中明确定义了依赖关系--jsonld。

但现在,你得到错误 jsonldProvider不存在(或类似) - 因为角度注入来自他的DI容器的依赖关系(https://docs.angularjs.org/guide/di

注册jsonld到DI容器可能看起来像

angular.module('....')
  .factory('jsonld', function() {  // string jsonld is name of service in DI container
    return jsonld; // this is global variable - jsonld library
  })

最后我们可以编写测试和模拟jsonld - 结果在这里http://plnkr.co/edit/6xdVwJsJba8SVZ6d6lgg?p=preview

如果使用$ http,使用$ httpBackend可以更轻松地进行测试,但jsonld是外部库,并且不在内部使用$ http。因此测试更复杂。