Jasmine框架在Angular单元测试中的应用

在现代Web开发中,单元测试是确保代码质量的重要手段。Angular框架因其强大的模块化和组件化特性,使得单元测试变得尤为重要。Jasmine作为一个流行的JavaScript行为驱动开发(BDD)测试框架,因其简洁的语法和独立于浏览器、DOM或其他JS框架的特性,成为了Angular单元测试的首选工具。本文将详细介绍如何在Angular应用中使用Jasmine进行单元测试。

Jasmine框架简介

Jasmine是一个行为驱动开发(BDD)框架,适用于JavaScript。它支持测试驱动开发(TDD)方法,并提供了组织测试的结构和断言功能。Jasmine的语法简单,易于理解,是独立于浏览器、DOM或其他JS框架的。

在Jasmine中,有几个关键术语需要了解:

  • Spec(规格):在BDD术语中,Spec是测试的逻辑分组。
  • Describe(描述):Describe函数代表一个规格(测试的逻辑分组)。
  • It(它):It函数指示逻辑分组中的一个测试。
  • Expect(期望):Expect(期望)接受一个值,称为实际值,用于测试。
  • toBe(是):toBe函数接受一个表达式,称为匹配器。每个匹配器在实际值和期望值之间进行布尔比较。
  • BeforeEach(在每个测试之前):BeforeEach函数允许用户在每个测试之前运行代码。

设置Jasmine环境

要将Jasmine集成到代码中,需要下载Jasmine git仓库提供的脚本文件和CSS文件。可以在以下链接找到这些文件,或者简单地在应用程序中包含CDN链接。

Jasmine主页链接:

CDN链接:

创建一个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’的规格,并测试3和4的和是否等于6,这是错误的。如果运行测试,那么显示将会是:

编写Angular控制器的测试

现在,将对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测试运行器。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485