2016-06-22 8 views
2

Ich versuche, eine asynchrone Methode in einem AngularJS-Dienst zu testen, der intern eine andere Async-Funktion mit Jasmine und Karma aufruft.Unit Tests AngularJS verspricht mit ES6

Hier ist, wie mein Dienst wie folgt aussieht:

export default class SearchUserAPI { 

    constructor(BaseService, $q) { 
    this.q_ = $q; 
    this.service_ = BaseService; 
    } 

    isActive(email) { 
    const params = {'email': email}; 

    return this.service_.getUser(params).then(isActive => { 
     // This part cannot be reached. 
     console.log('Is Active'); 
     // I need to test the following logic. 
     return isActive ? true : this.q_.reject(`User ${email} is not active.`); 
    }); 
    } 
} 

Und hier ist, wie mein Test wie folgt aussieht:

import SearchUserApi from './api.service'; 

let service, 
    mockedService, 
    $q; 

const email = '[email protected]'; 
const expectedParams = {email: email}; 

describe('Search API unit tests', function() { 

    beforeEach(inject(_$q_ => { 
    $q = _$q_; 
    mockedService = {}; 

    service = new SearchUserApi(mockedService, $q); 
    })); 

    // This test passes, but it doesn't reach the logging statement in main method. 
    it('is verifying that Chuck Norris should be active',() => { 
    // Trying to mock getUser() to return a promise that resolves to true. 
    mockedService.getUser = jasmine.createSpy('getUser').and.returnValue($q.when(true)); 

    service.isActive(email).then(result => { 
     // The following should fail, but since this part is called asynchronously and tests end before this expression is called, I never get an error for this. 
     expect(result).toBe(false); 
    }); 
    // This test passes, but I'm not too sure how I can verify that isActive(email) returns true for user. 
    expect(mockedService.getUser).toHaveBeenCalledWith(expectedParams); 
    }); 
}); 

ich in einer Menge Tutorials zu sehen, sie sprechen $ Umfang über die Verwendung und gelten Prüfen Sie, ob eine Bereichsvariable geändert wurde. Aber in meinem Fall manipuliere ich keine Instanz (Scope) -Variable, um $ scope.apply() zu verwenden.

Irgendeine Idee, wie ich den Test machen kann, auf meine asynchronen Anrufe zu warten, um aufgelöst zu werden, bevor sie enden?

Antwort

2

Ich fand heraus, wie man durch die asynchrone Methode geht. Alles, was ich tun musste, war $ rootScope und $ rootScope. $ Digest() nach dem Aufruf der asynchronen Methode, auch wenn ich Scope-Variablen innerhalb meines Tests nicht zu berühren.

+0

Es ist nicht asynchron. $ q Versprechen sind synchron, hängen aber von Digest ab und erfordern, dass es manuell ausgelöst wird. Überprüfen Sie https://github.com/bvaughn/jasmine-promise-matchers, um diese Aufgabe zu erleichtern. – estus