[譯] 如何對 Angular Controller 進行單元測試

原文地址:http://www.bradoncode.com/blog/2015/05/17/angularjs-testing-controller/
@Bradley Braithwaite javascript

圖片描述

上面一篇文章簡單介紹瞭如何使用 Jasmine 進行JavaScript的單元測試html

咱們用了一段簡單的代碼進行計算的測試。vue

接下來咱們將其延伸到咱們對Angular Controller的測試中。若是你不太瞭解angular也不要緊,下文也會說起關於Angular的一些知識。java

寫個簡單的Angular App

在開始寫測試以前,咱們先寫一個簡單的計算App,它會計算兩個數字之和。git

angular-calc.gif

代碼以下:angularjs

<html>
    <head>
        <script type="text/javascript" src="https://code.angularjs.org/1.4.0-rc.2/angular.min.js"></script>
    </head>
    <body>
        <!-- This div element corresponds to the  CalculatorController we created via the JavaScript-->
        <div ng-controller="CalculatorController">
            <input ng-model="x" type="number">
            <input ng-model="y" type="number">
            <strong>{{z}}</strong>
            <!-- the value for ngClick maps to the sum function within the controller body -->
            <input type="button" ng-click="sum()" value="+">
        </div>
    </body>
    <script type="text/javascript">

        // Creates a new module called 'calculatorApp'
        angular.module('calculatorApp', []);

        // Registers a controller to our module 'calculatorApp'.
        angular.module('calculatorApp').controller('CalculatorController', function CalculatorController($scope) {
          $scope.z = 0;
          $scope.sum = function() {
            $scope.z = $scope.x + $scope.y;
          };
        });
        
        // load the app
        angular.element(document).ready(function() {
               angular.bootstrap(document, ['calculatorApp']);
        });

    </script>
</html>

簡單說說裏面涉及的一些基本概念:github

建立一個 module

什麼是angular.module?它是用於建立,回收模塊的地方
。咱們建立一個名爲calculatorApp新的模塊,咱們並將組件添加到這個模塊裏。bootstrap

angular.module('calculatorApp', []);

關於第二個參數?第二個參數必須的,代表咱們正在創造一個新的模塊。若是須要咱們的應用程序有其餘的依賴,咱們能夠將它們['ngResource','ngCookies']傳入進去。
第二個參數的存在的表示這是一個請求返回的模塊的實例。segmentfault

從概念上講,它本意是相似下面的意思:api

* angular.module.createInstance(name, requires);
* angular.module.getInstance(name)

然而實際咱們是這樣寫的:

* angular.module('calculatorApp', []); // i.e. createInstance
* angular.module('calculatorApp'); // i.e. getInstance

關於module的更多信息 https://docs.angularjs.org/api/ng/function/angular.module

2.給module添加controller

接着咱們給angular module的示例添加一個controller

angular.module('calculatorApp').controller('CalculatorController', function CalculatorController($scope) {
  $scope.z = 0;
  $scope.sum = function() {
    $scope.z = $scope.x + $scope.y;
  };
});

控制器主要負責業務邏輯和視圖綁定,$scope者是視圖的控制器直線的信使。

3.鏈接視圖中的元素

在下面 HTML 中,咱們須要計算input裏面的值,而這些都包含在這個controller的div中。

<div ng-controller="CalculatorController">
    <input ng-model="x" type="number">
    <input ng-model="y" type="number">
    <strong>{{z}}</strong>
    <!-- the value for ngClick maps to the sum function within the controller body -->
    <input type="button" ng-click="sum()" value="+">
</div>

input 中的ng-model綁定的的值及時$scope上定義的好比$scope.x,咱們還在button元素使用ng-click綁定了$scope.sum方法。

添加測試

接下來終於到了咱們的主題,添加一些單元測試給controller,咱們忽略代碼中html部分,主要集中在controller的代碼中。

angular.module('calculatorApp').controller('CalculatorController', function CalculatorController($scope) {
  $scope.z = 0;
  $scope.sum = function() {
    $scope.z = $scope.x + $scope.y;
  };
});

爲了測試 controller,咱們還得說起下面幾點?

  • 如何建立一個controller實例

  • 如何get/set一個對象的屬性

  • 如何調用$scope裏面的函數

describe('calculator', function () {
        
    beforeEach(angular.mock.module('calculatorApp'));

    var $controller;

    beforeEach(angular.mock.inject(function(_$controller_){
      $controller = _$controller_;
    }));

    describe('sum', function () {
        it('1 + 1 should equal 2', function () {
            var $scope = {};
            var controller = $controller('CalculatorController', { $scope: $scope });
            $scope.x = 1;
            $scope.y = 2;
            $scope.sum();
            expect($scope.z).toBe(3);
        });    
    });

});

開始前咱們須要引入ngMock,咱們在測試的代碼加入angular.mock

,ngMock模塊提供了一種機制進行諸如以及虛擬的service進行單元測試。

如何獲取controller的實例

使用ngMock咱們能夠註冊一個calculator app實例。

beforeEach(angular.mock.module('calculatorApp'));

一旦calculatorApp初始化後,咱們可使用inject函數,這樣能夠解決controller的引用問題。

beforeEach(angular.mock.inject(function(_$controller_) {
    $controller = _$controller_;
}));

一旦app加載完了,咱們使用了inject函數,$controller service能夠獲取 CalculatorController 的實例。

var controller = $controller('CalculatorController', { $scope: $scope });

如何get/set一個對象的屬性

在上篇代碼中咱們已經能夠獲取一個controller的實例,在括號的第二個參數實際是controller本身,咱們的controller只有一個參數
$scope對象

function CalculatorController($scope) { ... }

在咱們的測試中$scope表明的就是一個簡單的JavaScript對象。

var $scope = {};
var controller = $controller('CalculatorController', { $scope: $scope });
// set some properties on the scope object
$scope.x = 1;
$scope.y = 2;

咱們設置x,y的值,模擬剛纔的gif中的所展現的同樣。咱們贊成也能夠讀取對象中的屬性,就像下面這段測試的斷言:

expect($scope.z).toBe(3);

如何調用$scope裏面的函數

最後一件事情就是咱們如何模擬用戶的點擊,就像咱們在絕大多數JS中使用的一致,,其實就是簡單的調用函數就行,

$scope.sum();

運行效果以下

vued4068b08f7b7c733c64971a5ab9c58320.png

小結

本篇文章簡單的基本的介紹瞭如何對angular controller進行單元測試,可是這是創建在不停的刷新瀏覽器基礎上,
而這些流暢能夠再好,也是咱們後面的一篇文章 如何使用karam進行 angular 測試 (翻譯中...)的所要說的。

完整代碼:https://github.com/JackPu/angular-test-tutorial/blob/master/angular-test.html

相關文章
相關標籤/搜索