2017-08-01 10 views
3

Jasmineで非同期コードをテストするときに予期しない動作が発生しています。私たちが知る限り、done関数を使用しているときは、doneが実行されるまで期待値は呼び出されません。しかし、それは第二期待が失敗しているので、それゆえ$ctrl.todos割り当てはテストジャスミンで非同期関数をテストする

を働いていない

が起こったことはありませんが起こっていない

it('initializes the data when $onIinit', (done) => { 
    const expected = 'some result'; 
    const response = Promise.resolve(expected); 

    spyOn(myService, 'getAll').and.returnValue(response); 

    // This method calls myService.getAll 
    $ctrl.$onInit(); 

    expect(myService.getAll).toHaveBeenCalled(); 
    expect($ctrl.todos).toEqual(false); 

    response.then(done); 
}); 

出力:一方

偽等しくなるように、未定義の期待、これは動作しています:

it('initializes the data when $onIinit', (done) => { 
    const expected = 'some result'; 
    const response = Promise.resolve(expected); 

    spyOn(myService, 'getAll').and.returnValue(response); 

    // This method calls myService.getAll 
    $ctrl.$onInit(); 

    expect(myService.getAll).toHaveBeenCalled(); 
    response 
     .then(() => expect($ctrl.todos).toBe(expected)) 
     .then(done); 
    }); 

出力:テスト合格

コントローラ方法:

$ctrl.$onInit =() => { 
    myService.getAll().then((data) => { 
    $ctrl.todos = data; 
    }); 
}; 

答えて

1

解決策が見つかりました。私は本当に別のthenを必要としません。 doneの仕様は、完了するまで完了しません。また、常に期待通りに配置する必要があります。

の作業コード:

it('initializes the data when $onIinit', (done) => { 
    const expected = 'some result'; 
    const response = Promise.resolve(expected); 
    spyOn(myService, 'getAll').and.returnValue(response); 
    $ctrl.$onInit(); 

    expect(myService.getAll).toHaveBeenCalled(); 
    response 
    .then(() => { 
     expect($ctrl.todos).toBe(expected); 
     done(); 
    }); 
}); 
0

あなたのaproachは正しいように思われ、おそらくafterEachdoneを呼び出すと、それが動作するようになります。

afterEach(function(done) { 
    done(); 
}, 1000); 

しかし、私は$httpBackend$http serviceを使用するユニットテストアプリケーションに適した偽のHTTPのバックエンドの実装を使用することをお勧めします。とにかくangularjsを使用しています。ですから、なぜ活用しないのですか?

$httpBackendとすると、実際のリクエストを実際のサーバに送信することなく、模擬データを使ってリクエストを作成できます。ここで

it('initializes the data when $onIinit',() => { 
    const mockData = { data: { expected: 'some result' } }; 

    spyOn(myService, 'getAll').and.callThrough(); 

    $httpBackend.expect('POST', '/my-service/url').respond(200, mockData); 

    // This method calls myService.getAll 
    $ctrl.$onInit(); 

    //flush pending request 
    $httpBackend.flush(); 

    expect(myService.getAll).toHaveBeenCalled(); 
    expect($ctrl.todos).toBeDefined(); 
}); 

いくつかの説明、$httpBackend.expect('POST', '/my-service/url')例ilustrativeは、ここ'POST'myService.getAllにあなたのサービスで使用されるmethodと一致する必要があることに注意してください、と'/my-service/url'myService.getAllであなたのサービスでも使用urlです。

$httpBackend.flush();に電話する必要があります。保留中のリクエストをすべて解放します。

あなたは、あなたのテストに$httpBackendを注入する必要がありますが、簡単な方法はまた

describe('$httpBackend service in module ngMock',() => { 
    let $httpBackend; 

    beforeEach(inject(['$httpBackend', (_$httpBackend) => { 
     $httpBackend = _$httpBackend; 
    }])); 

    it('$httpBackend is defined',() => { 
     // here we can use $httpBackend 
     expect($httpBackend).toBeDefined(); 
    }); 
}); 

なり、$httpBackendngMockモジュールの一部であることに注意してください。 here

はそれが

-1

Promiseを役に立てば幸いangularjsコードをテストについて

詳細情報は、外部の角度世界からです - あなたは、次のイベントキューティックで利用できるようになり、結果を待つ必要が - 汚い(ほとんど汚れ)ハックはsetTimeout

angular.module('test', []) 
 
    .controller('underTest', function($scope, myService) { 
 
    $scope.$onInit = function() { 
 
     myService.getAll().then(function(data) { 
 
     $scope.todos = data 
 
     }) 
 
    } 
 
    }) 
 

 
describe('Controller: somethingChanged', function() { 
 
    var scope, myService 
 

 
    beforeEach(function() { 
 
    module('test') 
 
    }) 
 

 
    beforeEach(function() { 
 
    module(function($provide) { 
 
     $provide.value('myService', { 
 
     getAll: function() {} 
 
     }) 
 
    }) 
 
    }) 
 

 
    beforeEach(inject(function($controller, _$rootScope_, _myService_) { 
 
    myService = _myService_ 
 
    scope = _$rootScope_.$new() 
 
    $controller('underTest', { 
 
     $scope: scope 
 
    }) 
 
    })) 
 

 
    it('initializes the data when $onIinit', function(done) { 
 
    const expected = 'some result' 
 
    const response = Promise.resolve(expected) 
 

 
    spyOn(myService, 'getAll').and.returnValue(response) 
 

 
    scope.$onInit() 
 

 
    expect(myService.getAll).toHaveBeenCalled(); 
 

 
    setTimeout(function() { 
 
     expect(scope.todos).toEqual(expected) 
 
     done() 
 
    }) 
 
    }); 
 
});
<script src="https://cdn.jsdelivr.net/jasmine/2.6.1/jasmine.js"></script> 
 
<script src="https://cdn.jsdelivr.net/jasmine/2.6.1/jasmine-html.js"></script> 
 
<script src="https://cdn.jsdelivr.net/jasmine/2.6.1/boot.js"></script> 
 
<link rel="stylesheet" href="https://cdn.jsdelivr.net/jasmine/2.6.1/jasmine.css" /> 
 

 
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-mocks.js"></script>

を使用することです
関連する問題