我开始为我的角应用程序编写单元测试。 然而,在我看来,我使用了很多样板代码来初始化和测试控制器。
在这个单元测试中,我想测试在执行函数时是否将范围中的模型发送到Api。
我需要20行代码。这使得编写仅执行一项操作的单元测试变得不方便。 您是否有任何关于将代码大小变为较小块的提示?
这是我目前的单元测试:
'use strict';
describe('controllers', function(){
beforeEach(module('kronos'));
describe('CustomerSignupCtrl', function() {
it('should send customer to Api on submit', inject(function($controller) {
var scope = {};
var $location = {};
var Api = {
signupCustomer: function(customer) {
expect(customer).toEqual({attrs: "customerdata"});
return {
success: function() { return this; },
error: function() { return this; }
};
}
};
var ctrl = $controller('CustomerSignupCtrl', {
$scope: scope,
$location: location,
Api: Api});
scope.customer = {attrs: "customerdata"};
scope.signup();
}));
});
});
我特别不喜欢的是以下几点
如何让这段代码更短更明确?
编辑:我刚注意到我可以忽略此单元测试的$location
服务。大
Edit2 :我发现了angular-app,这是一个很好的做法示例应用。在那里你可以找到specs with jasmine,它们写得非常好。
答案 0 :(得分:0)
在describe范围中使用另一个beforeEach方法来设置范围,$ location,controller等,然后根据需要在测试中更改它们。 Js是动态的,所以一切都应该没问题。
您还可以提取您设置到函数中的每个对象,以便在需要时可以在测试中重新初始化它们。
describe('controllers', function(){
beforeEach(module('kronos'));
describe('CustomerSignupCtrl', function() {
var controller, scope, $location, Api;
beforeEach(function(){
scope = {};
$location = {};
Api = {
signupCustomer: function(customer) {
expect(customer).toEqual({attrs: "customerdata"});
return {
success: function() { return this; },
error: function() { return this; }
};
}
};
controller = makeController();
})
function makeController(){
inject(function($controller){
controller = $controller('CustomerSignupCtrl', {
$scope: scope,
$location: location,
Api: Api});
});
}
it('should send customer to Api on submit', function() {
scope.customer = {attrs: "customerdata"};
scope.signup();
});
});
});
答案 1 :(得分:0)
您无法缩短代码。初始化,模拟和断言等事情必须在某个地方完成。但是,您可以通过解耦初始化和测试代码来提高代码的可读性。像这样:
describe('CustomerSignupCtrl', function(){
var controller, scope, location, api;
beforeEach(module('kronos'));
// initialization
beforeEach(inject(function($controller, $rootScope, $location, Api){
scope = $rootScope.$new();
location = $location;
api = Api;
controller = $controller('CustomerSignupCtrl', {
$scope: scope, $location: location, Api: api});
}));
// test
it('should send customer to Api on submit', function() {
scope.customer = {attrs: "customerdata"};
spyOn(api,'signupCustomer').andCallFake(function(customer) {
return {
success: function() { return this; },
error: function() { return this; }
};
});
scope.signup();
expect(api.signupCustomer).toHaveBeenCalledWith(scope.customer);
});
});