2015-07-12 167 views
6

我在這裏有一個指令我試圖編寫一個單元測試 - 第一次做這種類型的事情。我不知道如何去做。這裏的指令代碼和HTML:編寫單元測試的密碼匹配指令

app.directive('passwordMatch', [function() { 
 
    return { 
 
     restrict: 'A', 
 
     scope:true, 
 
     require: 'ngModel', 
 
     link: function (scope, elem, attrs, control) { 
 
      var checker = function() { 
 
       var e1 = scope.$eval(attrs.ngModel); 
 
       var e2 = scope.$eval(attrs.passwordMatch); 
 
       if(e2!=null) 
 
       return e1 == e2; 
 
      }; 
 
      scope.$watch(checker, function (n) { 
 
       control.$setValidity("passwordNoMatch", n); 
 
      }); 
 
     } 
 
    }; 
 
}]);
<form name="signupForm"> 
 
<div class="form-group"> 
 
\t \t 
 
\t  <div class="col-sm-7"> 
 
\t   <span class="block input-icon input-icon-right"> 
 
\t  <input type="password" class="register" name="password" placeholder="Password" ng-model="signup.password" required/> 
 
\t \t \t </span> 
 
\t  </div> 
 
\t </div> 
 
\t <div class="form-group"> \t 
 
\t  <div class="col-sm-7"> 
 
\t   <span class="block input-icon input-icon-right"> 
 
\t \t \t <input type="password" class="register" name="password2" placeholder="Confirm Password" ng-model="signup.password2" password-match="signup.password" required/>         
 
\t \t \t <small class="errorMessage" data-ng-show="signupForm.password2.$dirty && signupForm.password2.$error.passwordNoMatch && !signupForm.password2.$error.required"> Password do not match.</small> 
 
\t \t \t </span> 
 
\t  </div> 
 
\t </div> 
 
</form>

這裏就是我努力了測試。因此,對,這是給我一個錯誤的閱讀類型錯誤:「未定義」不是一個對象(評估「scope.signup.password =‘123’」)

describe('passwordMatch Directive - ', function() { 
 
    
 
    var scope, $compile, $window, element; 
 
     
 
    beforeEach(function() { 
 
     module('myApp'); 
 
     inject(function(_$compile_, _$rootScope_, _$window_) { 
 
     $compile = _$compile_; 
 
     scope = _$rootScope_.$new(); 
 
     $window = _$window_; 
 
     }) 
 
     
 
    }) 
 

 
    it('should indicate invalid when the passwords do not match.', function() { 
 
     scope.signup.password = '123'; 
 
     scope.signup.password2 = '1234'; 
 
     element = $compile(angular.element('<input type="password" class="register" name="password" placeholder="Password" ng-model="signup.password" required/> <input type="password" class="register" name="password2" placeholder="Confirm Password" ng-model="signup.password2" password-match="signup.password" required/>'))(scope); 
 
     scope.$apply(); 
 
     console.debug('element html - ' + element.html()); 
 
     expect(element.html().indexOf('ng-invalid')).toBeGreaterThan(0); 
 
    }); 
 

 
    it('should indicate valid when the passwords do not match.', function() { 
 
     scope.signup.password = '123'; 
 
     scope.signup.password2 = '123'; 
 
     element = $compile(angular.element('<input type="password" class="register" name="password" placeholder="Password" ng-model="signup.password" required/> <input type="password" class="register" name="password2" placeholder="Confirm Password" ng-model="signup.password2" password-match="signup.password" required/>'))(scope); 
 
     scope.$apply(); 
 
     console.debug('element html - ' + element.html()); 
 
     expect(element.html().indexOf('ng-valid')).toBeGreaterThan(0); 
 
    }); 
 
});

有些幫助將是非常感謝

編輯:我只是注意到當註釋掉scope.signup.password = '123'等,調試語句不會返回任何東西 - 只是DEBUG: 'element html - ',所以element.html()沒有做任何事情?

回答

4

我還沒有做過一段時間的測試,但是您是否嘗試過先定義scope.signup對象,或許在beforeEach塊中。所以,像,

describe('passwordMatch Directive - ', function() { 

    var scope, $compile, $window, element, elm; 

    beforeEach(function() { 
     module('myApp'); 
     inject(function(_$compile_, _$rootScope_, _$window_) { 
     $compile = _$compile_; 
     scope = _$rootScope_.$new(); 
     $window = _$window_; 
     }); 


     // define scope.signup as an empty object literal to which 
     // you can add properties later 
     scope.signup = {}; 

     // don't think you meant to have this so commenting it out 
     //elm 
    }) 

    it('should indicate invalid when the passwords do not match.', function() { 
     scope.signup.password = '123'; 
     scope.signup.password2 = '1234'; 
     element = $compile(angular.element('<input type="password" class="register" name="password" placeholder="Password" ng-model="signup.password" required/> <input type="password" class="register" name="password2" placeholder="Confirm Password" ng-model="signup.password2" password-match="signup.password" required/>'))(scope); 
     scope.$apply(); 
     console.debug('element html - ' + element.html()); 
     expect(element.html().indexOf('ng-invalid')).toBeGreaterThan(0); 
    }); 

    // etc... 
}); 

編輯

我認爲你需要有一個表單中輸入的。試試這個...

describe('passwordMatch Directive - ', function() { 

    var scope, $compile, $window, element, html; 

    beforeEach(function() { 

     module('myApp'); 

     inject(function(_$compile_, _$rootScope_, _$window_) { 
     $compile = _$compile_; 
     scope = _$rootScope_.$new(); 
     $window = _$window_; 
     }); 

     scope.signup = {}; 

     // inputs need to be within a form for you directive to work 
     html = '<form name="signupForm">' + 
       '<input type="password" class="register" name="password" placeholder="Password" ng-model="signup.password" required/>' + 
       '<input type="password" class="register" name="password2" placeholder="Confirm Password" ng-model="signup.password2" password-match="signup.password" required/>' + 
       '</form>'; 

    }); 

    it('should indicate invalid when the passwords do not match.', function() { 
     scope.signup.password = '123'; 
     scope.signup.password2 = '1234'; 
     element = $compile(angular.element(html))(scope); 
     scope.$apply(); 
     console.debug('element html - ' + element.html()); 
     expect(element.html().indexOf('ng-invalid')).toBeGreaterThan(0); 
    }); 

    it('should indicate valid when the passwords do not match.', function() { 

     scope.signup.password = '123'; 
     scope.signup.password2 = '123'; 

     element = $compile(angular.element(html))(scope); 

     scope.$apply(); 
     console.debug('element html - ' + element.html()); 
     expect(element.html().indexOf('ng-valid')).toBeGreaterThan(0); 
    }); 
}); 

EDIT 2

您可以直接從範圍上的這些屬性訪問的FormController的屬性也和作出斷言,而不是使用element.html()。使其更具可讀性。

it('should indicate invalid when the passwords do not match.', function() { 


     scope.signup.password = '123'; 
     scope.signup.password2 = '1234'; 

     element = $compile(angular.element(html))(scope); 
     scope.$apply(); 

     // expect(element.html().indexOf('ng-invalid')).toBeGreaterThan(0); 

     expect(scope.signupForm.$valid).toBe(false); 
     expect(scope.signupForm.$invalid).toBe(true); 

    }); 

    it('should indicate valid when the passwords do not match.', function() { 

     scope.signup.password = '123'; 
     scope.signup.password2 = '123'; 

     element = $compile(angular.element(html))(scope); 

     scope.$apply(); 

     //expect(element.html().indexOf('ng-valid')).toBeGreaterThan(0); 

     expect(scope.signupForm.$valid).toBe(true); 
     expect(scope.signupForm.$invalid).toBe(false); 
    }); 
+0

嘿,是的,我試過了。我只注意到,當我這樣做時,我沒有得到未定義的錯誤,但測試失敗,並且調試語句顯示element.html()沒有做任何事情,所以它的另一個問題是: – realization

+0

嘗試將輸入在你的模板裏面一個表格中查看更新後的答案 –

+0

你是一個嚮導:) :) – realization