在我的案例中如何解决单元测试问题?

时间:2016-08-05 16:49:24

标签: javascript angularjs unit-testing karma-runner

我正在尝试对两个函数代码进行单元测试,并不断收到未定义对象的错误。

我的控制器

vm = this;
//always fire first in the app
vm.getCompany = function() {
    api.getCompany(function(res){        
        //do stuff
    })
}

//always fire second in the app
vm.getEmployee = function() {
    api.getEmployee(function(res){
        //do stuff
    })
}

api服务

var company;

function getCompany() {
   var company;
   var q = $q.defer();
   var url = ‘something.com’;

   anotherApi.getCompany(url).then(function(comp){
          company = comp;
          q.resolve(company)
    })
}

function getEmployee = function() {
    var name = company.name
    var url = ‘something.com/’ + name;
    var q = $q.defer();
    anotherApi.getEmployee(url).then(function(employee){
          q.resolve(employee)
    })
}

单元测试。

beforeEach(function(){
   module(‘myApp);
        inject(function ($injector) {
            $controller = $injector.get('$controller');
            $rootScope = $injector.get('$rootScope');
            $scope = $rootScope.$new();
            $httpBackend = $injector.get('$httpBackend');
            api = $injector.get('api');
        });

         vm = $controller'myCtrl', {
            $scope : $scope
        });

})

describe (‘test’, function(){
    it(‘should get company’, function(){
         vm.getCompany();
         $httpBackend.flush();
         // stuff and works
    })
    it(‘should get Employee’, function(){
        vm.getEmployee()
        $httpBackend.flush();
        //getting error says 
        //'undefined' is not an object (evaluating 'company.name’)
    })
})

我得到了'undefined' is not an object (evaluating 'company.name’)getEmployee服务中的功能。

我尝试了很多不同的方法,但仍然不确定如何修复它,有人可以帮助我吗?谢谢!

2 个答案:

答案 0 :(得分:0)

问题出在您的服务中。 "公司"应该是对象文字,因为你访问.name,否则它将通过你指定的错误。

尝试以下代码:

服务

var company = {};

function getCompany() {
    $http.get(url).then(function(comp){
          company = comp;
          return company;
    })
}

function getEmployee = function() {
    var name = company.name
    $http.get(url).then(function(employee){
        // do stuff    
    }
}

它应该有用。

答案 1 :(得分:0)

如果在调用getCompany之前调用getEmployee,那么服务的预期行为是什么?在尝试使用公司之前,您至少应检查公司是否为空。此外,您可能需要考虑将公司存储在您可以在服务中访问的属性中。注意:我在属性名称前面加上一个下划线,只是为了区分public api和这个伪私有属性:

{
    _company: null,
    getCompany: function() {
        var self = this;
        var url = '...';
        return $http.get(url).then(function(comp){
            self._company = comp;
            return self._company;
        });
    },
    getEmployee: function() {
        var self = this;
        if (!self._company) {
            return null; //or throw error or return rejected promise: $q.reject('company is null')
        } else {
            var url = '...';
            var name = self._company.name;
            return http.get(url);
        }
    }
}

最后,您现在可以(并且应该)从您的控制器单独测试您的服务。在您的控制器测试中,您可以在不调用服务器的情况下监视您的服务方法。当您测试服务时,您可以在测试getEmployee方法时将service._company设置为模拟值。