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
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
ふるてつ
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
280
はじめてのSpringBoot
furutetsu
0
500
AngularとBootstrapを使った業務システムの設計について考えた。
furutetsu
1
2.4k
Other Decks in Programming
See All in Programming
脅威をエンジニアリングの糧にして――現場編 / Turning Threats into Engineering Fuel — Field Edition
nrslib
0
260
Datadog × OpenTelemetry 入門と実践のあいだ
kn_to_maxpno
1
150
運用エージェントは "作る" から "育てる" へ - 記憶と自己進化の3層設計パターン / self-evolving-agents-three-layer-agent-design
gawa
12
3.6k
Vite+ Unified Toolchain for the Web
naokihaba
0
170
Copilot CLI の継戦能力を高める コンテキスト管理
nozomutu
1
1.2k
Skillsは効率化、Agentsは"自分の拡張"——Builder時代のエージェント編成(CC Night 2026)
wemra
1
110
Why Laravel apps break—Mastering the fundamentals to keep them maintainable
kentaroutakeda
1
340
AI時代の仕事技芸論 — ソフトウェア開発で「遊ぶように働く」職人的熟達のすすめ
kuranuki
1
640
Javaの型とAI時代に型が大事な理由 / java types and type in AI era
kishida
2
120
AI時代のUIはどこへ行く?その2!
yusukebe
19
6.9k
ふつうのFeature Flag実践入門
irof
7
3.6k
Swiftのレキシカルスコープ管理
kntkymt
0
220
Featured
See All Featured
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Automating Front-end Workflow
addyosmani
1370
210k
Designing Experiences People Love
moore
143
24k
How STYLIGHT went responsive
nonsquared
100
6.2k
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.3k
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9.1k
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
300
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.5k
Exploring anti-patterns in Rails
aemeredith
3
400
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
200
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
140
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
118
120k
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
ありがとうございました。