简体   繁体   中英

How to unit test a controller with callback in AngularJS

I have a controller that has a callback inside:

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

My problem is that I need to check the value of "result" in an unit test, but if I just call ctrl.test(data) and then ctrl.result, the value of ctrl.result is {} and it should be what was returned by the test function (inside jsonld.expand). Is there a way to test this behavior (test the self.result when the callback occurs)?

I already searched around, but everything I found is related to custom services, but in this case this is an external library .

If you want to test your code, you must comply with certain rules. For example don't use global variables/dependencies.

In your example is jsonld global dependency. In unit tests we test only one component, dependencies are replaced with mocks.

How modify the code to be better testable?

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

The only difference is explicitly defined dependency in controller constructor - jsonld.

But now, you get error jsonldProvider does not exists (or similar) - because angular inject dependencies from his DI container ( https://docs.angularjs.org/guide/di )

Registration jsonld to DI container might look like

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

Finally we are able to write test and mock jsonld - result is here http://plnkr.co/edit/6xdVwJsJba8SVZ6d6lgg?p=preview

if you use $http, testing will be easier with $httpBackend, but jsonld is external library and don't use $http internally. Therefore the test is more complicated.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM