Angular の Unit Testing — Part 5 http testing
ใครยังไม่ได้อ่าน Part 4 คลิ๊กบทความด้านล่างเข้าไปอ่านได้ก่อนนะครับ
Recap จากตอนที่แล้วๆมา เราพูดถึงในเรื่องของ
- ข้อดีของการเขียนเทส
- อธิบาย describe, beforeEach และ it เบื้องต้น
- เขียนและรันเทสเคสแบบง่ายๆ
- การม็อคค่า(by pass) ด้วย SpyOn
- การม็อค service ด้วย SpyObject
- Asynchronous Testing
ปัจจุบัน Version ที่ผมใช้เขียนคือ Angular 8 นะครับ
คราวนี้จะมาเขียนเรื่องการเทส HTTP requests กันครับ จริงๆเรื่องนี้ถือว่าสำคัญมากสำหรับการเขียนเทสเลย เพราะค่อนข้างจะใช้บ่อยมากในชีวิตจริง เพราะเรามักจะต้องยิง api ไปหา Back-End อยู่บ่อยๆ
โดยปกติเราจะใช้ service ในเป็นตัวกลางในการ call api กัน ก็เลยจะต้องสร้าง service สำหรับเรียกใช้ HTTP requests กันก่อน
ผมมี service กับ model ชื่อ user-data หน้าตาประมาณนี้ มีการ import HttpClient มาใช้ กับโดยมี function getUserData() เป็น HTTP GET และ return ค่าเป็น Observable
และใน app module ก็ import HttpClientModule มาเพื่อให้ user-data service สามารถ import HttpClient มาใช้ได้
และไฟล์ spec ของผม ที่ ng เค้า default generate ออกมาให้หน้าตาเป็นแบบนี้
มาลอง run test กันก่อนด้วย ng test
run แล้วได้ Error ประมาณนี้ No Provider for HttpClient
เป็นเพราะเรา Inject HttpClient เข้าไปใน Service ของเรา แต่ในไฟล์เทสของเรา ไม่ได้ import ให้ไว้ใน TestBed
เราต้องไป import เพิ่มให้ TestBed ก่อน ตรงส่วนของ configureTestingModule
เราใช้ HttpClientTestingModule ที่ไฟล์ spec เพื่อจำลองแทนการ import HttpClientModule ใน app.module ส่วน HttpTestingController ที่ import เข้ามา แทนการทำงานของตัว HttpClient ที่เรา import มาใน service
ซึ่งเจ้าตัว HttpTestingController นั้นถือว่ามีความสำคัญกับเราอย่างมาก เพราะเค้าจะมาช่วยเราในการจ mocking และจำลองการ return ของจาก api กลับมาให้เรา ทำให้เราสามารถทำ test ได้โดยที่ไม่ต้อง request ไป api นั้นจริงๆ
คราวนี้มาเริ่มเขียนเทสกันต่อได้เลย โดยเราจะเทสฟังก์ชั่น getUserData
เราสร้าง test case มาประมาณนี้
เราลองมาดูโค้ดทั้งหมดกันครับ
ลำดับการทำงานจะเรียงประมาณนี้
แล้วถ้าจะให้ HttpClient flush Response Error ออกมาล่ะ ?
เราก็จะให้ตัว request flush HttpErrorResponse ออกมาแทน แล้วตอนที่เรา subscribe มันก็จะเข้าเคส error แทน
ปล. import { HttpErrorResponse } from ‘@angular/common/http’; มาด้วย
เป็นยังไงกันบ้างครับสำหรับการทำเทส HTTP เบื้องต้น จริงๆ HttpTestingController ยังมี function อื่นให้เรียกใช้งานอีก ลองไปอ่านไปเพิ่มได้ที่เว็บ Angular กันดูครับ