2016-07-11 4 views
3

Ich versuche eine AngularJS Komponente mit Karma, Mocha, Power-Assert zu testen. Ich habe ein Textfeld und eine Schaltfläche in meiner Komponente, wo die Schaltfläche basierend auf der Länge des Textes in Textarea deaktiviert ist.Angularjs Komponententest - ng-disable funktioniert nicht, wenn Text zu textarea hinzugefügt wird

Wenn ich die Komponente im Browser ausführen, funktioniert es perfekt. Aber ich kann nicht herausfinden, wie man diese Funktionalität testet.

Hier ist ein bisschen Code.

inquiryForm.js

function inquiryForm($scope) { 
    // i plan to add some logic here 
} 
angular.module('myApp').component('inquiryForm', { 
    controller: inquiryForm, 
    controllerAs: 'inquiryForm', 
    templateUrl: 'inquiryForm.html' 
}); 

inquiryForm.html

<div class="contact"> 
    <div>Thanks for contacting us.</div> 
    <form> 
     <textarea ng-model="inquiryForm.inquiryText" name=""></textarea> 
     <input type="submit" value="SEND" ng-disabled="!inquiryForm.inquiryText.length"> 
    </form> 
</div> 

inquiryFormTest.js

describe('inquiry form ',() => { 
    let $rootScope; 
    let $scope; 
    let $compile; 
    let element; 

    beforeEach(() => { 
    angular.mock.module('myApp'); 

    inject(($injector) => { 
     $rootScope = $injector.get('$rootScope'); 
     $scope = $rootScope.$new(); 
     $compile = $injector.get('$compile'); 
    }); 
    }); 

    const compileDirective =() => { 
    element = $compile('<inquiry-form></inquiry-form>')($scope); 
    $scope.$digest(); 
    }; 

    describe('inquiry form',() => { 
    beforeEach(() => { 
     compileDirective(); 
    }); 

    // this test passes 
    it('disables the submit button if textbox is empty',() => { 
     assert(element.find('input').prop('disabled'), true); 
    }); 

    // this test fails 
    it('enables the submit button if textbox is not empty',() => { 
     // making some changes to DOM here 
     element.find('textarea').text('hello, world!'); 
     console.log(element.find('textarea').text()); // expected: "hello, world!", actual: "hello, world!" 

     // since the state of scope has changed, I call digest to reflect those 
     $scope.$digest(); 

     // this assert passes 
     assert(element.find('textarea').text(), 'hello, world!'); 

     // this one fails. 
     assert(element.find('input').prop('disabled'), false); 
    }); 
    }); 
}); 

Wie Sie oben in den Kommentaren sehen kann, schlägt der zweite Test. Ich vermute, der Test ist fehlgeschlagen, da der Status von HTML nicht in den Komponentencontroller inquiryForm widergespiegelt wurde. Sicher, das DOM von Textarea wird aktualisiert, aber die ng-disabled Direktive wird nicht ausgelöst, da der Komponentencontroller inquiryForm nicht mit dem Oszilloskop verbunden ist.

Wie kann ich diese ng-disabled Feuer mit mock Benutzereingabe in Textbereich machen ...

+0

Sie haben 'describe'd die' Anfrage form'. Haben Sie versucht, den from name = "inquiry form" zu nennen? – mattymanme

+0

@mattymanme ich glaube nicht, dass der Wert von 'describe' in unittest mit dem eckigen js-Objekt verknüpft werden kann. Ich habe es trotzdem versucht und es hat nicht funktioniert. –

Antwort

0

Nach vielen Suchen und Versuch und Irrtum, ich habe endlich die Lösung gefunden. Wie ich vermutete, wurde das Ändern von Text in Textarea nicht an die Komponentensteuereinheit übermittelt, weshalb die ng-disabled="!inquiryForm.inquiryText.length", die den Verweis darauf enthält, nicht ausgelöst wurde.

Hier ist, wie ich mein Testcode geändert ...

// this test fails 
it('enables the submit button if textbox is not empty',() => { 
    // making some changes to DOM here 
    // ↓---↓ REMOVED THIS 
    // element.find('textarea').text('hello, world!'); 
    // ↑---↑ this was just making changes to DOM but was not informing the component controller of those changes. 

    // ↓+++↓ ADDED THIS 
    angular.element(element.find('textarea')).val('hello, world!').triggerHandler('change'); 
    // ↑+++↑ I used the .val() and .triggerHandler() of angularjs to inform component of changes in state of scope 

    // since the state of scope has changed, I call digest to init the watchers 
    $scope.$digest(); 

    // now this assert passes 
    assert(element.find('input').prop('disabled') === false); 
}); 

Referenz: https://stackoverflow.com/a/26376249/6573907

0

verwenden Sie das Formular Benennung wie folgt:

<form name="inquiry form" ng-submit="inquiryForm.handleSubmit()" method="post"> 
+0

danke für deine antwort. Das funktioniert nicht. Die ng-disable-Direktive funktioniert nicht, selbst nachdem der Wert von textarea geändert wurde. –

Verwandte Themen