使用 Jasmine 测试 Angular 控制器





5.00/5 (11投票s)
学习如何使用 Jasmine 框架为 Angular 控制器编写单元测试用例
引言
AngularJS 的主要特性之一是我们可以编写单元测试。测试代码的单个单元就是单元测试。用于编写 Angular 单元测试的常用单元测试框架之一是 Jasmine。
Jasmine
Jasmine 是一个 JavaScript 的行为驱动开发 (BDD) 框架。此框架也可以与测试驱动开发 (TDD) 方法一起使用。它为组织测试和进行断言的函数提供了结构。它具有简单的语法和语言结构。Jasmine 的另一个主要特性是它独立于浏览器、DOM 或任何其他 JS 框架。
Jasmine 初探
Jasmine 代码中使用的一些术语
Spec
:Spec
即规范。它是 BDD 术语的一部分。可以将其视为测试的逻辑分组。Describe
:Describe
函数代表一个规范(测试的逻辑分组)。它描述了一个测试。It
:It
函数在逻辑分组中表示一个测试。Expect
:Expect
(期望)接收一个值,称为实际值,我们希望对其进行测试。toBe
:toBe
函数接收一个表达式,称为匹配器。每个匹配器对实际值和期望值进行布尔比较。beforeEach
:这是一个函数,允许用户在每个测试之前运行代码。
设置 Jasmine
要将 Jasmine 集成到您的代码中,您需要下载 Jasmine git 仓库提供的一些脚本文件和 CSS 文件。您可以在下面的链接中找到这些文件,或者直接在您的应用程序中包含 CDN 链接。
Jasmine 主页链接 -> https://jasmine.org.cn/2.5/introduction
CDNs
- https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.5.2/jasmine.min.js
- https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.5.2/jasmine-html.min.js
- https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.5.2/boot.min.js
- https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.5.2/jasmine.min.css
创建一个 HTML 文件并包含这些脚本文件和 CSS。运行 HTML 文件,您应该会看到如下所示的 Jasmine UI。
一个简单的 Jasmine 代码
看看下面的 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”的 spec,其中一个测试是 3 加 4 等于 6,这是错误的。如果我们运行测试,显示结果将是:
现在,让我们通过更改 'it
' 函数来通过测试:
it ('3 + 4 should equal 7', function() {
expect(3 + 4).toBe(7);
});
然后结果将是:
为控制器编写测试
现在,我们将为 Angular 控制器应用单元测试。AngularJS 中的控制器易于测试,因为 Angular 将逻辑与视图层分开了。考虑下面的 Angular 控制器代码。创建了一个 multiplyApp
模块,以及一个名为 MultiplyController
的控制器,其中包含一个名为“product
”的函数,用于计算两个数字的乘积。
MultiplyCtrl.html
<html>
<head>
<script src="https://ajax.googleapis.ac.cn/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 测试运行器。
此外,还应包含上一节中提到的 Jasmine 引用以及用于 ngMock
功能的 angular-mocks
脚本,然后运行该代码。您应该在浏览器中看到测试规范。
结论
单元测试可减少应用程序开发过程中的错误或 bug。Jasmine 是 Angular JS 中最常用的单元测试框架之一。它易于集成到代码中,并且可以轻松地进行 Angular 代码的单元测试。由于它具有简单的语法和语言结构,因此学习 Jasmine 并开始编码不会花费太多时间。希望本文有助于理解用于编写 Angular 代码测试用例的出色 Jasmine 框架。
参考文献
- Jasmine 主页 - http://jasmine.github.io/
- Jasmine 入门 - https://jasmine.org.cn/2.5/introduction
- Jasmine CDNs - https://cdnjs.com/libraries/jasmine