如何解决我的单元测试问题?
How to fix the unit test issue in my case?
我正在尝试对两个函数代码进行单元测试,但不断收到未定义对象的错误。
我的控制器
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
功能下。
我已经尝试了很多不同的方法,但仍然不确定如何解决它,有人可以帮助我解决这个问题吗?谢谢!
问题出在您的服务中。 "company" 应该是对象文字,因为您通过它访问 .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
}
}
应该可以。
如果在调用 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 设置为模拟值。
我正在尝试对两个函数代码进行单元测试,但不断收到未定义对象的错误。
我的控制器
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
功能下。
我已经尝试了很多不同的方法,但仍然不确定如何解决它,有人可以帮助我解决这个问题吗?谢谢!
问题出在您的服务中。 "company" 应该是对象文字,因为您通过它访问 .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
}
}
应该可以。
如果在调用 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 设置为模拟值。