2013-07-13 7 views
19

में निर्देश परीक्षण में एनजी-परिवर्तन कैसे ट्रिगर करें मेरे पास निम्न AngularJS निर्देश है जो input तत्व बनाता है। इनपुट में ng-change विशेषता है जो doIt() फ़ंक्शन चलाती है। मेरे निर्देशक इकाई परीक्षण में मैं यह जांचना चाहता हूं कि doIt फ़ंक्शन को कॉल किया जाता है जब उपयोगकर्ता इनपुट बदलते हैं। लेकिन परीक्षण पास नहीं होता है। हालांकि मैन्युअल रूप से परीक्षण करते समय यह ब्राउज़र में काम करता है।AngularJS

निर्देशक:

... 
template: "<input ng-model='myModel' ng-change='doIt()' type='text'>" 

टेस्ट:

el.find('input').trigger('change') // Dos not trigger ng-change 

लाइव डेमो (एनजी-परिवर्तन): http://plnkr.co/edit/0yaUP6IQk7EIneRmphbW?p=preview


अब, परीक्षण गुजरता है, तो मैं मैन्युअल बजाय change घटना बाँध ng-change विशेषता का उपयोग करने के लिए।

template: "<input ng-model='myModel' type='text'>", 
link: function(scope, element, attrs) { 
    element.bind('change', function(event) { 
    scope.doIt(); 
    }); 
} 

लाइव डेमो (मैनुअल बंधन): http://plnkr.co/edit/dizuRaTFn4Ay1t41jL1K?p=preview


वहाँ ng-change उपयोग करें और यह परीक्षण योग्य बनाने के लिए एक तरीका है? धन्यवाद।

+1

एनजी-परिवर्तन मॉडल परिवर्तनों पर ट्रिगर किया गया है, घटनाओं पर नहीं। क्यों न केवल अपने "doIt" fn के लिए नियंत्रक कोड का परीक्षण करें? – marko

+0

@marko, अच्छे प्रश्न के लिए धन्यवाद। मैं निर्देशक के परीक्षण में जो करना चाहता हूं वह यह जांचना है कि जब उपयोगकर्ता इनपुट बदलता है तो उसे बुलाया जाता है। ऐसा ही निर्देशक के परीक्षण में मजाक किया जाएगा, क्योंकि जैसा कि आपने सुझाव दिया है, यह पहले से ही नियंत्रक के परीक्षण में परीक्षण किया गया है। – Evgenii

उत्तर

30

अपने व्याख्यात्मक टिप्पणी से:

सभी मैं निर्देश के परीक्षण में क्या करना चाहते हैं यह देखना होगा कि doIt जब उपयोगकर्ता इनपुट बदलता है कहा जाता है।

या नहीं, अभिव्यक्ति ng-change ने संकेत सही ढंग से मूल्यांकन किया है या नहीं है वास्तव में ngModel निर्देश की जिम्मेदारी है, तो मुझे यकीन है कि मैं इस तरह से यह परीक्षण होता नहीं हूँ, इसके बजाय, मुझे विश्वास होगा कि ngModel और ngChange निर्देशों को निर्दिष्ट फ़ंक्शन को कॉल करने के लिए सही ढंग से कार्यान्वित और परीक्षण किया गया है, और केवल यह जांचें कि फ़ंक्शन को कॉल करने से ही सही तरीके से निर्देश को प्रभावित किया जा सके। पूर्ण-उपयोग परिदृश्य को संभालने के लिए एक एंड-टू-एंड या एकीकरण परीक्षण का उपयोग किया जा सकता है।

कहा कि, आप ngModelController उदाहरण है कि ngModel परिवर्तन कॉलबैक ड्राइव की पकड़ हो और दृश्य मान अपने आप को सेट कर सकते हैं: जैसा कि मैंने कहा

it('trigger doIt', function() { 
    var ngModelController = el.find('input').controller('ngModel'); 
    ngModelController.$setViewValue('test'); 
    expect($scope.youDidIt).toBe(true); 
}); 

, हालांकि, मुझे लगता है कि यह बहुत तक पहुंच रहा है ngModel की ज़िम्मेदारियों में, काले-मुक्केबाजी को तोड़कर आप स्वाभाविक रूप से संगत निर्देशों के साथ मिलते हैं।

उदाहरण: http://plnkr.co/edit/BaWpxLuMh3HvivPUbrsd?p=preview


[अपडेट]

AngularJS स्रोत पर चारों ओर देखने के बाद, मैंने पाया कि निम्नलिखित भी काम करता है:

it('trigger doIt', function() { 
    el.find('input').trigger('input'); 
    expect($scope.youDidIt).toBe(true); 
}); 

ऐसा लग रहा है कुछ ब्राउज़रों में घटना अलग है; input क्रोम के लिए काम करता प्रतीत होता है।

उदाहरण:

changeInputValueTo = function(value) { 
    inputElm.val(value); 
    browserTrigger(inputElm, $sniffer.hasEvent('input') ? 'input' : 'change'); 
}; 

यहां तक ​​कि इस होने, मुझे यकीन है कि मैं एक परीक्षण था नहीं कर रहा हूँ: http://plnkr.co/edit/rbZ5OnBtKMzdpmPkmn2B?p=preview

यहाँ relevant AngularJS code है, जो यह पता लगाने की जो घटना को गति प्रदान करने $sniffer सेवा का उपयोग करता है इस तरह से निर्देश।

+4

घटनाओं के बारे में, मुझे लगता है कि 'इनपुट' टेक्स्ट इनपुट के लिए है और जैसे' चेंज 'चुनिंदा बॉक्स और रेडियो बटन के लिए है। कम से कम यही मेरे लिए फैंटॉमजेएस पर परीक्षण चलाने के लिए काम कर रहा है। –

+1

ऐसा लगता है ब्राउज़र ट्रिगर केवल कोणीय -दृश्य.जेएस में मौजूद है। इसका मतलब है कि यह केवल e2e परीक्षण के लिए है, है ना? मैं इस फ़ंक्शन को यूनिट टेस्ट में उपयोग करने में सक्षम नहीं हूं, जिसका उद्देश्य मैं मानता हूं। – unludo

+0

@unludo शायद; मेरा मुद्दा केवल इतना था कि AngularJS स्रोत कुछ ब्राउज़रों में एक अलग घटना को ट्रिगर करने के लिए लिखा गया था। –

0

मैं लंबे समय तक इस सरल रेखा की तलाश में था। बस इसे यहां सहेजने के लिए।

कर्म का उपयोग करके एचटीएमएल-चयन से मूल्य का चयन कैसे करें, और इसलिए एनजी-चेंज फ़ंक्शन काम कर रहा है?

HTML:

नियंत्रक या निर्देश जे एस:

$scope.itemTypes = [{name: 'Some name 1', value: 'value_1'}, {name: 'Some name 2', value: 'value_2'}] 

    $scope.itemTypeSelected = function() { 
    console.log("Yesssa !!!!"); 
    }; 

कर्मा परीक्षण टुकड़ा:

angular.element(element.find("#selectedItemType")[0]).val('value_1').change(); 
    console.log("selected model.selectedItemType", element.isolateScope().model.selectedItemType); 

कंसोल:

'Yesssa !!!!' 
'selected model.selectedItemType', 'value_1' 
0

मैंने "कोणीय निर्देश ट्रिगर एनजी-चेंज" को गुगल किया और यह स्टैक ओवरफ्लो प्रश्न निकटतम था जो मुझे कुछ भी उपयोगी था, इसलिए मैं जवाब दूंगा कि "निर्देश में एनजी-चेंज कैसे ट्रिगर करें", क्योंकि अन्य इस पृष्ठ पर उतरने के लिए बाध्य हैं , और मुझे नहीं पता कि यह जानकारी कैसे प्रदान की जाए।

निर्देश पर लिंक समारोह के अंदर, यह आपके तत्व पर एनजी-परिवर्तन समारोह को गति प्रदान करेगा:

element.controller('ngModel').$viewChangeListeners[0](); 

element.trigger("change") और element.trigger("input") मेरे लिए काम नहीं किया, न तो कुछ और मैं ऑनलाइन मिल सकता था।

उदाहरण के लिए, कलंक पर एनजी-परिवर्तन ट्रिगर:

wpModule.directive('triggerChangeOnBlur', function() { 
    return { 
     restrict: 'A', 
     link: function (scope, element, attrs) { 
      element.on('blur', function() { 
       element.controller('ngModel').$viewChangeListeners[0](); 
      }); 
     } 
    }; 
}]); 

मुझे खेद है कि यह सीधे ओपी के प्रश्न का उत्तर नहीं है हूँ। इस जानकारी को कहां और कैसे साझा किया जाए, इस बारे में कुछ अच्छी सलाह लेने के लिए मुझे खुशी होगी।

+1

आदर्श रूप से, आप एक अलग प्रश्न पूछेंगे और फिर इसे स्वयं जवाब दें (अजीब लगता है, लेकिन इसे प्रोत्साहित किया जाता है)। मैं कुछ ऐसी चीज भी ढूंढ रहा हूं जो ओपी, या आपकी समस्या नहीं है, और अगर इसके बारे में विशेष रूप से कोई सवाल था तो इसका उत्तर तेजी से मिल जाएगा। –

0

सरल और यह काम करता अपने इकाई परीक्षण env में:

spyOn(self, 'updateTransactionPrice'); 


var el = compile('<form name="form" latest novalidate json-schema="main.schema_discount" json-schema-model="main._data"><input type="text" ng-model="main._data.reverse_discount" ng-class="{ \'form-invalid\': form.reverse_discount.$invalid }" ng-change="main.transactionPrice(form);" name="reverse_discount" class="form-control-basic" placeholder="" ng-disabled="!main.selectedProduct.total_price"></form>')(scope); 
el.find('input').triggerHandler('change'); 

expect(self.updateTransactionPrice).toHaveBeenCalled(); 
0

इस काम करने के लिए प्राप्त करने की कोशिश कर रहा है, लेकिन हर प्रयास असफल रहा। आखिर में निष्कर्ष निकाला कि ऑनअपडेट पर एक deboun सेटिंग के साथ मेरे एनजी मॉडल विकल्प, समस्या थी।

यदि आपके पास कोई बहस है, तो सुनिश्चित करें कि आप $ टाइमआउट सेवा के साथ फ़्लश करें। कोणीय नकली में, इस टाइमआउट सेवा को फ्लश ऑपरेशन के साथ बढ़ा दिया गया है, जो सभी अपूर्ण अनुरोध/कार्यों को संभालता है।

var tobetriggered = angular.element(element[0].querySelector('.js-triggervalue')); 
    tobetriggered.val('value'); 
    tobetriggered.trigger('change'); 
    $timeout.flush();