在现代Web开发中,单元测试是确保代码质量的重要手段。Angular框架因其强大的模块化和组件化特性,使得单元测试变得尤为重要。Jasmine作为一个流行的JavaScript行为驱动开发(BDD)测试框架,因其简洁的语法和独立于浏览器、DOM或其他JS框架的特性,成为了Angular单元测试的首选工具。本文将详细介绍如何在Angular应用中使用Jasmine进行单元测试。
Jasmine是一个行为驱动开发(BDD)框架,适用于JavaScript。它支持测试驱动开发(TDD)方法,并提供了组织测试的结构和断言功能。Jasmine的语法简单,易于理解,是独立于浏览器、DOM或其他JS框架的。
在Jasmine中,有几个关键术语需要了解:
要将Jasmine集成到代码中,需要下载Jasmine git仓库提供的脚本文件和CSS文件。可以在以下链接找到这些文件,或者简单地在应用程序中包含CDN链接。
Jasmine主页链接:
CDN链接:
创建一个HTML文件,并包含这些脚本文件和CSS。运行HTML文件,应该看到以下Jasmine UI:
查看以下HTML代码。script标签包括执行测试代码所需的Jasmine脚本文件。代码中还包含了Jasmine CSS文件,有助于显示测试执行的Jasmine UI。
<html>
<head>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.5.2/jasmine.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.5.2/jasmine.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.5.2/jasmine-html.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.5.2/boot.min.js"></script>
</head>
<body>
</body>
<script type="text/javascript">
describe('addition', function() {
it('3 + 4 should equal 7', function() {
expect(3 + 4).toBe(6);
});
});
</script>
</html>
编写的测试代码被包含在script标签中。描述了一个名为‘addition’的规格,并测试3和4的和是否等于6,这是错误的。如果运行测试,那么显示将会是:
现在,将对Angular控制器进行单元测试。Angular JS的控制器很容易测试,因为Angular将逻辑与视图层分离。考虑以下Angular控制器代码。创建了一个名为multiplyApp的模块,以及一个名为MultiplyController的控制器,其中包含一个名为product的函数,用于计算两个数的乘积。
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.9/angular.min.js"></script>
<script>
angular.module('multiplyApp', []);
angular.module('multiplyApp').controller('MultiplyController', function MultiplyController($scope) {
$scope.z = 0;
$scope.product = function() {
$scope.z = $scope.x * $scope.y;
}
});
</script>
</head>
<body ng-app="multiplyApp">
<div ng-controller="MultiplyController">
<input ng-model="x" type="number">
<input ng-model="y" type="number">
{{z}}
<input type="button" ng-click="product()" value="Multiply">
</div>
</body>
</html>
现在,将为这个控制器编写测试代码。由于控制器不在全局作用域中,需要使用angular.mock.inject来注入控制器。将使用angular-mocks提供的module函数。通过使用ngMock功能,注册应用程序的实例。
beforeEach(angular.mock.inject(function(_$controller_) {
$controller = _$controller_;
}));
将使用$controller服务获取MultiplyController的实例。
var controller = $controller('MultiplyController', {$scope: $scope});
花括号中的参数是控制器本身的参数。$scope对象是控制器的唯一参数。它可以由一个简单的JS对象表示。
var $scope = {};
var controller = $controller('MultiplyController', {$scope: $scope});
$scope.x = 2;
$scope.y = 3;
还可以像读取对象属性一样读取属性:
expect($scope.z).toBe(6);
在作用域对象上调用函数与对JavaScript函数的操作相同:
$scope.product();
现在,有测试代码:
describe('multiply', function() {
beforeEach(angular.mock.module('multiplyApp'));
var $controller;
beforeEach(angular.mock.inject(function(_$controller_) {
$controller = _$controller_;
}));
describe('product', function() {
it('2*3 should equal 6', function() {
var $scope = {};
var controller = $controller('MultiplyController', {$scope: $scope});
$scope.x = 2;
$scope.y = 3;
$scope.product();
expect($scope.z).toBe(6);
});
});
});
以上代码测试了MultiplyController,测试用例是2乘以3是否等于6。将以上代码包含在Angular应用程序中,例如MultiplyCtrl.html文件中的script标签内。可以将测试写在单独的JS文件中,并将其包含在应用程序中。对于这个示例,将测试代码写在同一个MultiplyCtrl.html文件中。如果想添加另一个测试,可以在测试代码中添加,但它不会在添加后自动运行。要做到这一点,使用Karma测试运行器。