Ste*_*how 15 javascript testing unit-testing jasmine angularjs
在Angular中,一切似乎都有一个陡峭的学习曲线,单元测试Angular应用程序肯定不会逃避这种范式.
当我开始使用TDD和Angular时,我觉得我花了两倍(或许更多)时间来确定如何测试,甚至更多只是让我的测试设置正确.但正如Ben Nadel在他的博客中所说,角度学习过程中有起伏.他的图表绝对是我对Angular的体验.
然而,随着我在学习Angular和单元测试方面取得了进展,现在我觉得我花费的时间少得多,设置测试的时候还有更多的时间让测试从红色变为绿色 - 这是一种很好的感觉.
所以我遇到了不同的方法来设置我的单元测试以模拟服务和承诺,我想我会分享我所学到的知识,并且还会问以下问题:
有没有其他或更好的方法来实现这一目标?
所以在代码上,无论如何我们都来这里 - 不是听一些人谈论他的爱,错误的成就学习框架.
这就是我开始嘲笑我的服务和承诺的方式,我将使用一个控制器,但服务和承诺显然可以在其他地方嘲笑.
describe('Controller: Products', function () {
var//iable declarations
$scope,
$rootScope,
ProductsMock = {
getProducts: function () {
} // There might be other methods as well but I'll stick to one for the sake of consiseness
},
PRODUCTS = [{},{},{}]
;
beforeEach(function () {
module('App.Controllers.Products');
});
beforeEach(inject(function ($controller, _$rootScope_) {
//Set up our mocked promise
var promise = { then: jasmine.createSpy() };
//Set up our scope
$rootScope = _$rootScope_;
$scope = $rootScope.$new();
//Set up our spies
spyOn(ProductsMock, 'getProducts').andReturn(promise);
//Initialize the controller
$controller('ProductsController', {
$scope: $scope,
Products: ProductsMock
});
//Resolve the promise
promise.then.mostRecentCall.args[0](PRODUCTS);
}));
describe('Some Functionality', function () {
it('should do some stuff', function () {
expect('Stuff to happen');
});
});
});
Run Code Online (Sandbox Code Playgroud)
对我们来说这很有效,但随着时间的推移,我认为必须有更好的方法.对于一个我讨厌的人
promise.then.mostRecentCall
Run Code Online (Sandbox Code Playgroud)
事情,如果我们想重新初始化控制器,然后我们不得不将其拉出beforeEach块和单独注射到每个测试.
一定有更好的方法...
现在我问是否有人有其他方法来设置测试,或者我选择这样做的想法或感觉?
Ste*_*how 12
然后我遇到了另一个帖子,博客,stackoverflow示例(你选择它我可能在那里),我看到了使用$ q库.咄!当我们可以使用Angular为我们提供的工具时,为什么要建立一个完整的模拟承诺.我们的代码看起来更好,看起来更有意义 - 没有丑陋的promise.then.mostRecent的东西.
接下来在单元测试的迭代中是这样的:
describe('Controller: Products', function () {
var//iable declarations
$scope,
$rootScope,
$q,
$controller,
productService,
PROMISE = {
resolve: true,
reject: false
},
PRODUCTS = [{},{},{}] //constant for the products that are returned by the service
;
beforeEach(function () {
module('App.Controllers.Products');
module('App.Services.Products');
});
beforeEach(inject(function (_$controller_, _$rootScope_, _$q_, _products_) {
$rootScope = _$rootScope_;
$q = _$q_;
$controller = _$controller_;
productService = _products_;
$scope = $rootScope.$new();
}));
function setupController(product, resolve) {
//Need a function so we can setup different instances of the controller
var getProducts = $q.defer();
//Set up our spies
spyOn(products, 'getProducts').andReturn(getProducts.promise);
//Initialise the controller
$controller('ProductsController', {
$scope: $scope,
products: productService
});
// Use $scope.$apply() to get the promise to resolve on nextTick().
// Angular only resolves promises following a digest cycle,
// so we manually fire one off to get the promise to resolve.
if(resolve) {
$scope.$apply(function() {
getProducts.resolve();
});
} else {
$scope.$apply(function() {
getProducts.reject();
});
}
}
describe('Resolving and Rejecting the Promise', function () {
it('should return the first PRODUCT when the promise is resolved', function () {
setupController(PRODUCTS[0], PROMISE.resolve); // Set up our controller to return the first product and resolve the promise.
expect('to return the first PRODUCT when the promise is resolved');
});
it('should return nothing when the promise is rejected', function () {
setupController(PRODUCTS[0], PROMISE.reject); // Set up our controller to return first product, but not to resolve the promise.
expect('to return nothing when the promise is rejected');
});
});
});
Run Code Online (Sandbox Code Playgroud)
这开始感觉应该像它应该设置的方式.我们可以模拟我们需要模拟的东西,我们可以设定解决和拒绝的承诺,这样我们就可以真正测试两种可能的结果.这感觉很好......
| 归档时间: |
|
| 查看次数: |
13105 次 |
| 最近记录: |