使用模拟测试 AngularJS 服务的初始化
Testing Initialization of AngularJS Service with Mocks
我正在尝试测试 angular 服务在初始化时响应它从另一个服务获得的值的方式,但我很难找到一种不笨拙的方式来做这件事.. .更不用说有效的了。
我要测试的服务看起来有点像这样:
angular.module('myApp')
.service('myService', function (Auth, DataGrabber) {
var self = this;
this.initialize = function () {
this.user = Auth.getUser();
if (!this.user.name) {
DataGrabber.grabName();
}
if (!this.user.birthday) {
DataGrabber.grabBirthday();
}
}
this.initialize();
})
这是我尝试测试的不太顺利的方法:
describe('myService', function () {
var myService;
var dataGrabberMock;
var authMock;
var grabbedName;
var grabbedBirthday;
beforeEach(function () {
module('myApp')
})
beforeEach(function() {
grabbedName = false;
grabbedBirthday = false;
authMock = {
getUser: function () {
return {
name: 'Bob',
birthday: 'Feb 22'
}
}
}
dataGrabberMock = {
grabName: function () {
grabbedName = true;
},
grabBirthday: function () {
grabbedBirthday = true;
}
}
module(function ($provide) {
$provide.value('Auth', authMock);
$provide.value('DataGrabber', dataGrabberMock);
})
})
it ('just gets info if all data is present', function () {
inject(function($injector) {
myService = $injector.get('myService');
expect(myService.user.name).toBe('Bob');
expect(myService.user.birthday).toBe('Feb 22');
});
});
it ('gets info if name is missing', function () {
// how do I stub the new user response here?
})
it ('calls birthdayGetter if birthday is missing', function () {
// here too?
})
})
更改 authMock 为每个测试提供的值的最简洁方法是什么?
我已经尝试了无数种不同的 inject()、$injector、$provide 和 spyOn() 组合。我终于通过设置存根和间谍并在测试中显式调用 myService.initialize() 来让它工作,但是每次测试的初始化代码都是 运行 两次,感觉不对。
我是 angular 测试的新手,所以作为新手,我可能忽略了一种更好的方法。
谢谢!
dataGrabberMock
赋值有误
要更改 authMock 的值,您可以创建一个单独的方法来设置模拟和一个注入服务的方法,并在您的测试中调用这两个方法。
beforeEach(function () {
grabbedName = false;
grabbedBirthday = false;
dataGrabberMock = {
grabName: function () {
grabbedName = true;
},
grabBirthday: function () {
grabbedBirthday = true;
}
};
spyOn(dataGrabberMock, 'grabName');
spyOn(dataGrabberMock, 'grabBirthday');
module(function ($provide) {
$provide.value('Auth', authMock);
$provide.value('DataGrabber', dataGrabberMock);
});
});
var authMock;
function setupAuthMock(name, birthday){
authMock = {
getUser: function () {
return {
name: name,
birthday: birthday
};
}
};
}
function setupAuthMockWithoutName(birthday){
authMock = {
getUser: function () {
return {
birthday: birthday
};
}
};
}
function setupAuthMockWithoutBirthday(name){
authMock = {
getUser: function () {
return {
name: name
};
}
};
}
function setupService() {
inject(function ($injector) {
myService = $injector.get('myService');
});
}
it('just gets info if all data is present', function () {
setupAuthMock('Bob', 'Feb 22');
setupService();
expect(myService.user.name).toBe('Bob');
expect(myService.user.birthday).toBe('Feb 22');
});
it('gets info if name is missing', function () {
setupAuthMockWithoutName('Feb 30');
setupService();
expect(dataGrabberMock.grabName).toHaveBeenCalled();
});
it('calls birthdayGetter if birthday is missing', function () {
setupAuthMockWithoutBirthday('Bob');
setupService();
expect(dataGrabberMock.grabBirthday).toHaveBeenCalled();
});
我又想了想,我认为使用单独的描述块比使用单独的方法更干净。
describe('myService', function () {
var myService;
var dataGrabberMock;
var authMock;
var grabbedName;
var grabbedBirthday;
beforeEach(function () {
module('myApp');
});
beforeEach(function () {
grabbedName = false;
grabbedBirthday = false;
dataGrabberMock = {
grabName: function () {
grabbedName = true;
},
grabBirthday: function () {
grabbedBirthday = true;
}
};
spyOn(dataGrabberMock, 'grabName');
spyOn(dataGrabberMock, 'grabBirthday');
module(function ($provide) {
$provide.value('Auth', authMock);
$provide.value('DataGrabber', dataGrabberMock);
});
});
describe('when all data is present', function () {
beforeEach(function () {
authMock = {
getUser: function () {
return {
name: 'Bob',
birthday: 'Feb 22'
};
}
};
});
beforeEach(function () {
inject(function ($injector) {
myService = $injector.get('myService');
});
});
it('just gets info', function () {
expect(myService.user.name).toBe('Bob');
expect(myService.user.birthday).toBe('Feb 22');
});
});
describe('when name is missing', function () {
beforeEach(function () {
authMock = {
getUser: function () {
return {
birthday: 'Feb 22'
};
}
};
});
beforeEach(function () {
inject(function ($injector) {
myService = $injector.get('myService');
});
});
it('gets info', function () {
expect(dataGrabberMock.grabName).toHaveBeenCalled();
});
});
describe('when birthday is missing', function () {
beforeEach(function () {
authMock = {
getUser: function () {
return {
name: 'Bob',
};
}
};
});
beforeEach(function () {
inject(function ($injector) {
myService = $injector.get('myService');
});
});
it('calls birthdayGetter', function () {
expect(dataGrabberMock.grabBirthday).toHaveBeenCalled();
});
});
});
我正在尝试测试 angular 服务在初始化时响应它从另一个服务获得的值的方式,但我很难找到一种不笨拙的方式来做这件事.. .更不用说有效的了。
我要测试的服务看起来有点像这样:
angular.module('myApp')
.service('myService', function (Auth, DataGrabber) {
var self = this;
this.initialize = function () {
this.user = Auth.getUser();
if (!this.user.name) {
DataGrabber.grabName();
}
if (!this.user.birthday) {
DataGrabber.grabBirthday();
}
}
this.initialize();
})
这是我尝试测试的不太顺利的方法:
describe('myService', function () {
var myService;
var dataGrabberMock;
var authMock;
var grabbedName;
var grabbedBirthday;
beforeEach(function () {
module('myApp')
})
beforeEach(function() {
grabbedName = false;
grabbedBirthday = false;
authMock = {
getUser: function () {
return {
name: 'Bob',
birthday: 'Feb 22'
}
}
}
dataGrabberMock = {
grabName: function () {
grabbedName = true;
},
grabBirthday: function () {
grabbedBirthday = true;
}
}
module(function ($provide) {
$provide.value('Auth', authMock);
$provide.value('DataGrabber', dataGrabberMock);
})
})
it ('just gets info if all data is present', function () {
inject(function($injector) {
myService = $injector.get('myService');
expect(myService.user.name).toBe('Bob');
expect(myService.user.birthday).toBe('Feb 22');
});
});
it ('gets info if name is missing', function () {
// how do I stub the new user response here?
})
it ('calls birthdayGetter if birthday is missing', function () {
// here too?
})
})
更改 authMock 为每个测试提供的值的最简洁方法是什么?
我已经尝试了无数种不同的 inject()、$injector、$provide 和 spyOn() 组合。我终于通过设置存根和间谍并在测试中显式调用 myService.initialize() 来让它工作,但是每次测试的初始化代码都是 运行 两次,感觉不对。
我是 angular 测试的新手,所以作为新手,我可能忽略了一种更好的方法。
谢谢!
dataGrabberMock
赋值有误要更改 authMock 的值,您可以创建一个单独的方法来设置模拟和一个注入服务的方法,并在您的测试中调用这两个方法。
beforeEach(function () {
grabbedName = false;
grabbedBirthday = false;
dataGrabberMock = {
grabName: function () {
grabbedName = true;
},
grabBirthday: function () {
grabbedBirthday = true;
}
};
spyOn(dataGrabberMock, 'grabName');
spyOn(dataGrabberMock, 'grabBirthday');
module(function ($provide) {
$provide.value('Auth', authMock);
$provide.value('DataGrabber', dataGrabberMock);
});
});
var authMock;
function setupAuthMock(name, birthday){
authMock = {
getUser: function () {
return {
name: name,
birthday: birthday
};
}
};
}
function setupAuthMockWithoutName(birthday){
authMock = {
getUser: function () {
return {
birthday: birthday
};
}
};
}
function setupAuthMockWithoutBirthday(name){
authMock = {
getUser: function () {
return {
name: name
};
}
};
}
function setupService() {
inject(function ($injector) {
myService = $injector.get('myService');
});
}
it('just gets info if all data is present', function () {
setupAuthMock('Bob', 'Feb 22');
setupService();
expect(myService.user.name).toBe('Bob');
expect(myService.user.birthday).toBe('Feb 22');
});
it('gets info if name is missing', function () {
setupAuthMockWithoutName('Feb 30');
setupService();
expect(dataGrabberMock.grabName).toHaveBeenCalled();
});
it('calls birthdayGetter if birthday is missing', function () {
setupAuthMockWithoutBirthday('Bob');
setupService();
expect(dataGrabberMock.grabBirthday).toHaveBeenCalled();
});
我又想了想,我认为使用单独的描述块比使用单独的方法更干净。
describe('myService', function () {
var myService;
var dataGrabberMock;
var authMock;
var grabbedName;
var grabbedBirthday;
beforeEach(function () {
module('myApp');
});
beforeEach(function () {
grabbedName = false;
grabbedBirthday = false;
dataGrabberMock = {
grabName: function () {
grabbedName = true;
},
grabBirthday: function () {
grabbedBirthday = true;
}
};
spyOn(dataGrabberMock, 'grabName');
spyOn(dataGrabberMock, 'grabBirthday');
module(function ($provide) {
$provide.value('Auth', authMock);
$provide.value('DataGrabber', dataGrabberMock);
});
});
describe('when all data is present', function () {
beforeEach(function () {
authMock = {
getUser: function () {
return {
name: 'Bob',
birthday: 'Feb 22'
};
}
};
});
beforeEach(function () {
inject(function ($injector) {
myService = $injector.get('myService');
});
});
it('just gets info', function () {
expect(myService.user.name).toBe('Bob');
expect(myService.user.birthday).toBe('Feb 22');
});
});
describe('when name is missing', function () {
beforeEach(function () {
authMock = {
getUser: function () {
return {
birthday: 'Feb 22'
};
}
};
});
beforeEach(function () {
inject(function ($injector) {
myService = $injector.get('myService');
});
});
it('gets info', function () {
expect(dataGrabberMock.grabName).toHaveBeenCalled();
});
});
describe('when birthday is missing', function () {
beforeEach(function () {
authMock = {
getUser: function () {
return {
name: 'Bob',
};
}
};
});
beforeEach(function () {
inject(function ($injector) {
myService = $injector.get('myService');
});
});
it('calls birthdayGetter', function () {
expect(dataGrabberMock.grabBirthday).toHaveBeenCalled();
});
});
});