2016-06-03 6 views
2

Jasmine zum ersten Mal zu lernen und ich bin auf diesen Fehler beim Versuch, die Fokus() -Funktion in einem eckigen Service zu testen stecken. Hier ist der Service:angularjs + jasmine: test fokus in einem service

myApp.service('MyService', function($timeout, $window) { 
    var service = { 
    focusElem: focusElem 
    }; 
    return service; 

    function focusElem(id) { 
    console.log('id of element is = ', id); 
    if (id) { 

     $timeout(function() { 
     var element = $window.document.getElementById(id); 
     console.log('element is = ', element); 
     if (element) { 
      element.focus(); 
     } 
     }); 
    } 
    }; 

}); 

Hier ist meine Spec-Datei

describe('myApp', function() { 
    var element, dummyElement; 
    beforeEach(function() { 
    // Initialize myApp injector 
    module('myApp'); 

    // Inject instance of service under test  
    inject(function($injector) { 
     MyServiceObj = $injector.get('MyService'); 
    }); 

    element = angular.element('<input id="firstName" name="firstName"/>'); 
    dummyElement = document.createElement('input'); 
    dummyElement.setAttribute('id', 'lastName'); 

    }); 

    it('should have focus if the focus Service is used on an element', function() { 
    console.info('------------------'); 
    spyOn(element[0], 'focus'); 
    spyOn(dummyElement, 'focus'); 
    MyServiceObj.focusElem(dummyElement.getAttribute('id')); 
    expect(dummyElement.focus).toHaveBeenCalled(); 
    }); 
}); 

Mein Fehler:

myApp should have focus if the focus Service is used on an element 
Expected spy focus to have been called. 
Error: Expected spy focus to have been called. 
+0

Mögliches Duplikat von [Jasmine mock chained Methoden mit Karma und Angular] (http://stackoverflow.com/questions/36285896/jasmine-mock-chained-methods-with-karma-and-angular) – estus

+0

Siehe auch http: //stackoverflow.com/a/33742298/3731501 Wenn "focus" ausspioniert ist "callThrough" und ein Fokusereignis auslöst. – estus

+0

Hat dies für Sie funktioniert? – tasseKATT

Antwort

1

Wenn Sie ngMock viele Dienste verwenden geändert werden, so dass sie in gesteuert werden eine synchrone Art und Weise innerhalb des Testcodes, um Ihnen mehr Kontrolle über den Fluss zu geben.

Einer der betroffenen Dienste ist $timeout.

Die in Ihrem Dienst an $timeout übergebene Funktion wird in Ihrem Test nicht ausgeführt, es sei denn, Sie teilen dies mit. Verwendung $timeout.flush() wie diese

es zu sagen, auszuführen:

spyOn(element[0], 'focus'); 

spyOn(dummyElement, 'focus'); 

MyServiceObj.focusElem(dummyElement.getAttribute('id')); 

$timeout.flush(); 

expect(dummyElement.focus).toHaveBeenCalled(); 

Beachten Sie, dass Sie einen Verweis auf die $timeout Service benötigen:

var element, dummyElement, $timeout; 

beforeEach(function() { 

    module('myApp'); 

    inject(function($injector, _$timeout_) { 

    MyServiceObj = $injector.get('MyService'); 

    $timeout = _$timeout_; 
    }); 

Das nächste Problem ist aufgrund der folgenden Zeile in Ihrem Service:

var element = $window.document.getElementById(id); 

Die Elemente, die Sie in Ihrem Test erstellen werden niemals an das DOM angehängt, so dass der Dienst sie nicht findet.

Die einfachste Lösung besteht darin, einfach Ihre Elemente an das DOM anzuhängen. In diesem Fall ist es wichtig, dass Sie sie nach dem Test manuell entfernen, da Jasmine das gleiche DOM für Ihre gesamte Testsuite verwendet.

Zum Beispiel:

it('should have focus if the focus Service is used on an element', function() { 

    var body = angular.element(document.body); 

    body.append(element); 
    body.append(dummyElement); 

    spyOn(element[0], 'focus'); 

    spyOn(dummyElement, 'focus'); 

    MyServiceObj.focusElem(dummyElement.getAttribute('id')); 

    $timeout.flush(); 

    expect(dummyElement.focus).toHaveBeenCalled(); 

    element.remove(); 
    dummyElement.remove(); 
}); 

Demo:http://plnkr.co/edit/F8xqfYYQGa15rwuPPbN2?p=preview

Nun, das Anbringen und Elemente auf das DOM während Unit-Tests zu entfernen ist nicht immer eine gute Sache zu tun und kann chaotisch.

Es gibt andere Möglichkeiten, um es zu behandeln, zum Beispiel durch Ausspionieren getElementById und Steuern des Rückgabewerts oder durch Mocking ein ganzes Dokument. Ich werde das hier jedoch nicht weiter ausführen, da ich sicher bin, dass es hier schon Beispiele gibt.

Verwandte Themen