Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Angularで簡単な画面を単体テストまで一通り作った件
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
ふるてつ
September 11, 2019
Programming
1.4k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Angularで簡単な画面を単体テストまで一通り作った件
ふるてつ
September 11, 2019
More Decks by ふるてつ
See All by ふるてつ
ユニットテストとE2Eテストをdemoしたい件
furutetsu
0
290
はじめてのSpringBoot
furutetsu
0
510
AngularとBootstrapを使った業務システムの設計について考えた。
furutetsu
1
2.5k
Other Decks in Programming
See All in Programming
PHP に部分適用が来るぞ!……ところで何それ?おいしいの? #phpcon / phpcon-2026
shogogg
0
660
PHP Application における Kubernetes 内 gRPC 通信
ganchiku
0
590
yield再入門 #phpcon
o0h
PRO
0
1.1k
ルールを書いて終わらせないハーネスエンジニアリング
yug1224
4
1.9k
Cloudflare is Agents
chimame
0
170
【QA Test Talk Vol.8】AI-DLC による Whole Team Approach の加速
pkshadeck
PRO
0
180
Go言語とトイモデルで学ぶTransformerの気持ち / fukuokago23-transformer
monochromegane
0
170
ドリフトを絶対に許さない(?)CDK運用 / CDK Ops with Zero Tolerance for Drifts (?)
akihisaikeda
1
190
生成AIで帳票OCRが「簡単に」作れる時代になった?
kon_shou
0
930
VibeCodingからAgenticWorkflowへ
starfish719
0
460
生成AI導入の「期待外れ」を乗り越える ー 開発フロー改革が目指す、真の組織変革
starfish719
0
4.4k
AI時代のPHPer生存戦略 ~「言語、もうなんでもよくない?」に本気で向き合う~
vivion
0
460
Featured
See All Featured
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
650
Between Models and Reality
mayunak
4
390
Rails Girls Zürich Keynote
gr2m
96
14k
Being A Developer After 40
akosma
91
590k
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.3k
Crafting Experiences
bethany
1
250
Marketing to machines
jonoalderson
1
5.7k
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
1
2.8k
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
410
Mobile First: as difficult as doing things right
swwweet
225
10k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.5k
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
410
Transcript
Angularで簡単な画面を 単体テストまで一通り作った件 Angular もくもく会 in Fukuoka #9 2019.9.11
自己紹介 福岡のエンジニアです。 客先常駐するタイプです。 COBOL → VB6.0 → VB.net → Spring
BootなIT人生。 他 jQuery → AngularJS → Angular 定年後の夢は、年金をもらいながら自称IT発明家になることです。 ふるてつ@tetsufuru19681 https://tetsufuru.hatenablog.com/ ちょくちょく参加するコミュニティ
今日のおはなし Angular Materialを使って簡単なマスタメンテ画面を作りました。 会社マスタメンテ画面とサービス 軽く動いたところで初テストコードを書きました。 Jasmineでサービス1つ、コンポーネント1つ 目新しいことは特にありませんが、せっかくなのでご紹介します。 ※HTML、CSSはまだあまりちゃんとしていません。
すこし実物を見ていただきます。
CompanyListComponent 検索条件:会社名、会社名カナ、削除フラグ ボタン:新規、クリア、検索 一覧:ページネーションあり、一覧をクリックすると詳細へジャンプ DIしているもの CompanyService(自前) FormBuilder Title Router
CompanyService メソッド getCompanyList(httpParams: HttpParams) getCompany(companySeq: number) createCompany(companyDto: CompanyDto) updateCompany(companyDto: CompanyDto)
DIしているもの HttpClient TranslateService ErrorMessageService(自前)
company.service.spec.ts(デフォルト) import { TestBed, inject } from '@angular/core/testing'; import {
CompanyService } from '../company/company.service'; xdescribe('CompanyService', () => { beforeEach(() => { TestBed.configureTestingModule({ providers: [CompanyService] }); }); it('should be created', inject([CompanyService], (service: CompanyService) => { expect(service).toBeTruthy(); })); });
company.service.spec.ts describe('CompanyService', () => { let companyService: CompanyService; let httpClientSpy:
{ get: jasmine.Spy, post: jasmine.Spy, put: jasmine.Spy }; let translateServiceSpy: { instant: jasmine.Spy }; beforeEach(() => { httpClientSpy = jasmine.createSpyObj('HttpClient', ['get', 'post', 'put']); translateServiceSpy = jasmine.createSpyObj('TranslateService', ['instant']); TestBed.configureTestingModule({ providers: [ CompanyService, ErrorMessageService, { provide: HttpClient, useValue: httpClientSpy }, { provide: TranslateService, useValue: translateServiceSpy },], }); companyService = TestBed.get(CompanyService); }); 追加 追加 追加
company.service.spec.ts it('#getCompanyList:should return expected SearchCompanyListDto (HttpClient called once)', () =>
{ const expectedSearchCompanyListDto: SearchCompanyListDto = new SearchCompanyListDto(); const searchCompanyDto: SearchCompanyDto[] = [{companySeq: BigInt('1'), companyName: 'companyName', ~ 中略 ~ updateUser: 'updateUser', updateTime: new Date}]; expectedSearchCompanyListDto.searchCompanyDtos = searchCompanyDto; httpClientSpy.get.and.returnValue(asyncData(expectedSearchCompanyListDto)); companyService.getCompanyList(null).subscribe( searchCompanyList => expect(searchCompanyList).toEqual(expectedSearchCompanyListDto, 'expected searchCompanyDto'),fail); expect(httpClientSpy.get.calls.count()).toBe(1, 'one call'); }); DTO SPY
company-list.component.spec.ts TestBed.configureTestingModule({ declarations: [CompanyListComponent], schemas: [NO_ERRORS_SCHEMA], imports: [ReactiveFormsModule, BrowserAnimationsModule, MaterialModule,
HttpClientModule, TranslateModule.forRoot({ loader: { provide: TranslateLoader, useFactory: HttpLoaderFactory, deps: [HttpClient] } }), ], providers: [ FormBuilder, ~ 以下略 ~ 追加 追加
company-list.component.spec.ts it('should entry company name', () => { const debugElement:
DebugElement = fixture.debugElement; const queriedElement = debugElement.query(By.css('#companyName')); const htmlInputElement: HTMLInputElement = queriedElement.nativeElement; const expectedEntry = 'abcd1234日本語'; htmlInputElement.value = expectedEntry; htmlInputElement.dispatchEvent(new Event('input')); expect(component.companyName.value).toEqual(expectedEntry); }); css selector event
テストした内容 company.service 4つのメソッド(getListXX、getXX、updateXX、createXX)×2(正常/エラー2通り) company-list.component TypeScript 「新規」「クリア」「検索」ボタンから呼ばれるメソッドのテスト 「結果一覧」リストをクリックした時に呼ばれるメソッドのテスト DOM 検索条件の項目名 検索条件の初期値
検索条件の入力値 検索用のhttpパラメータ値
None
None
課題・検討 無駄にspyを作った気がする。 [NO_ERRORS_SCHEMA]の使いどころをまだわかっていない。 DOMのテストの成果が良くわからない ⇒ DOMのカバレッジはない のか? Materialでidを追加したコードがブラウザで表示されると違うものに なる場合があった。 検索ボタンクリックのテストは
async ()=>でないと動かなかった。 DOMについて一覧のヘッダーやデータ行の内容を確認すべきか? 悩んだ。
参考サイト Material 環境:https://material.angular.io/guide/getting-started コントロール:https://material.angular.io/components/categories/forms 一覧関連:https://material.angular.io/components/categories/tables ページネーションのサンプル:https://material.angular.io/components/table/examples (上記URLの「Table retrieving data
through HTTP」にあります) テスト:https://angular.jp/guide/testing 上記URL内の「サービスのテスト」、「コンポーネントテストの基本」、「コンポーネントクラスのテスト」、「コンポーネント DOMのテスト」
わたしのブログ記事 Angular8 で Web アプリを作ろう - Jasmine - Serviceのテスト https://tetsufuru.hatenablog.com/entry/2019/08/13/130116
Angular8 で Web アプリを作ろう - Jasmine - Componentのテスト その1 https://tetsufuru.hatenablog.com/entry/2019/09/01/015709 Angular8 で Web アプリを作ろう - Jasmine - Componentのテスト その2 DOM https://tetsufuru.hatenablog.com/entry/2019/09/01/222413
ありがとうございました。