angular 4 TypeScriptジャスミンで単体テストをしたいサービスがあります。
現在、http
はpost
を実行しており、IDを返しますが、何も送信していません。
十分なコードカバレッジを設定したいのですが、このモックステートメントを完全に完成させる方法がわかりません。
これは私のサービスファイルでのhttp投稿の方法です
addSession() {
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.post(this.url, JSON.stringify({}), options)
.map((response: Response) => response.json());
}
そしてSPEC FILE、これは実際にテストするものを取得していません。サービスのhttpポストから返された数値を偽装していると思います。応答は000000014
仕様
import { TrackerFormService } from './tracker-form.service'
import { Observable } from 'rxjs/Observable'
describe('TrackerFormService', () => {
let trackerFormService: TrackerFormService,
mockHttp;
beforeEach(() => {
mockHttp = jasmine.createSpyObj('mockHttp', ['get', 'post', 'put']
)
trackerFormService = new TrackerFormService(mockHttp);
});
describe('addSession', () => {
it('add session ', () => {
// how to test, what to test?
// response , is a number? how to mock/fake this?
})
})
})
必要なモックを実現するために必要なモックは、POSTが通常行うのと同じ結果を返す単純な関数です。別のことは、テストがサーバーに実際にヒットしてはならないことです。このようなものが必要になります(他の依存関係を追加する必要があるかもしれません):
import { HttpModule } from '@angular/http';
import { TrackerFormService } from './tracker-form.service'
import { Observable } from 'rxjs/Observable'
describe('TrackerFormService', () => {
// Mock the service like this and add all the functions you have in this fashion
let trackerFormService: TrackerFormService,
mockService = {
addSession: jasmine.createSpy('addSession').and.returnValue(Observable.of('your session object mock goes here'))
};
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpModule],
providers: [{
provide: TrackerFormService,
useValue: mockService
}]
});
});
// Do this trick to inject the service every time, and just use `service` in your tests
beforeEach(inject([TrackerFormService], (trackerFormService) => {
service = trackerFormService;
}));
describe('addSession', () => {
it('add session ', () => {
let fakeResponse = null;
// Call the service function and subscribe to it to catch the fake response coming from the mock.
service.addSession().subscribe((value) => {
// in here value will be whatever you put as returnValue (remember to keep the observable.of())
fakeResponse = value;
});
// expects as in any test.
expect(fakeResponse).toBeDefined();
expect(fakeResponse).toBe('your session object mock goes here');
});
});
});
Angular 4.3には、Httpに取って代わり、HTTPリクエストをモックする簡単な方法を提供するHttpClientサービスが付属しています。公式ページに詳しく記載されています。 https://angular.io/guide/http
テスト/モックをセットアップした方法で、ポストコールの返信を偽装し、期待どおりの結果が得られたことを確認できます。そうすることで、模擬応答がマップステートメントによって適切に変換されることをテストします。スパイを使用して、postメソッドがどのように呼び出されたかを確認することもできます。これにより、オプションが予期したものと一致するかどうかが確認されます。
しかし、私の意見では、これはかなり複雑なソリューションです。メソッドを分割してモックやスパイを回避したいので、すべてのメソッドが1つのことだけを実行します。 addSessionメソッドが現在3つの異なる(まだ論理的に依存している)ことをしているためです。
メソッドを3つに分割すると、メソッド#1と#3を別々のテストで簡単にテストでき、メソッド#2にはhttpライブラリへの呼び出しのみが含まれます。これにより、httpライブラリを呼び出さなくても、上記と同じテスト値を達成できます。
方法#2についてはどうでしょうか...まだテストされていません。私の意見では、テストする理由はまったくありません。あなたがそのコードを書かなかったからです。また、あなたがangulars httpモジュールを使用しているなら、私は彼ら自身が確かなユニットテストを持っていると確信しています。
サービスの応答は、追加の統合テストですでにカバーされているはずです。実行頻度を下げて、サービスAPIが期待どおりの結果を返すことを確認してください。
コードカバレッジでその1行を本当にグリーンにしたい場合は、オプションでnockというライブラリを使用できます。 Nockはアプリが引き起こすすべてのxhrトラフィックをインターセプトします。テストファイルでは、xhrリクエストをnockオブジェクトを使用してモック応答にマッピングできます。
var scope = nock('http://myapp.iriscouch.com')
.post('/users', {
username: 'pgte',
email: '[email protected]'
})
.reply(201, {
ok: true,
id: '123ABC',
rev: '946B7D1C'
});
コピー元: https://www.npmjs.com/package/nock
一般的なテストのリファレンスと追加情報、およびテストの量については、Justin Searlsの「Budgeting Reality」を視聴することをお勧めします