การจำลองบริการและสิ่งที่ต้องพึ่งพา
จัดเตรียมออบเจ็กต์จำลองสำหรับการทดสอบผ่าน DI
การจำลองบริการและสิ่งที่ต้องพึ่งพา เป็นบทเรียน Angular Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Angular Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Angular Academy มีบทเรียนทั้งหมด 4 บทเรียน
เหตุผลที่ต้องจำลองการพึ่งพา
การทดสอบ component ควรแยก component ออกมา หาก component ฉีดบริการที่ทำงานด้วย HttpClient คุณคงไม่ต้องการเรียกเครือข่ายจริง แต่ควรจัดเตรียม ออบเจ็กต์ทดแทนสำหรับการทดสอบ ซึ่งเป็นออบเจ็กต์จำลองที่คืนข้อมูลที่ควบคุมได้ ทำให้การทดสอบรวดเร็วและให้ผลแน่นอน
การจัดเตรียมของจำลองผ่าน useValue
ออบเจ็กต์ทดแทนที่ง่ายที่สุดคือออบเจ็กต์ทั่วไปที่จัดเตรียมด้วย useValue ให้จัดเตรียมออบเจ็กต์นี้ภายใต้โทเค็นการฉีดเดียวกับที่ component ร้องขอ
const fakeApi = { getUser: () => of({ name: 'Ada' }) };
TestBed.configureTestingModule({
imports: [ProfileComponent],
providers: [{ provide: UserApi, useValue: fakeApi }],
});Spy ของ Jasmine
jasmine.createSpyObj สร้างออบเจ็กต์จำลองที่มีเมธอด spy ทำให้คุณกำหนดค่าที่คืนกลับมาและตรวจสอบการเรียกใช้ได้
const apiSpy = jasmine.createSpyObj<UserApi>('UserApi', ['getUser']);
apiSpy.getUser.and.returnValue(of({ name: 'Ada' }));
TestBed.configureTestingModule({
providers: [{ provide: UserApi, useValue: apiSpy }],
});การตรวจสอบว่าบริการถูกเรียกใช้
หลังจากดำเนินการกับ component แล้ว ให้ตรวจสอบว่า spy ได้รับอาร์กิวเมนต์ตามที่คาดไว้
fixture.componentInstance.load(7);
fixture.detectChanges();
expect(apiSpy.getUser).toHaveBeenCalledWith(7);
expect(apiSpy.getUser).toHaveBeenCalledTimes(1);การคืนค่า Observables จากออบเจ็กต์จำลอง
บริการมักคืนค่า Observables ใช้ RxJS of() สำหรับความสำเร็จแบบทำงานพร้อมกัน และใช้ throwError() สำหรับความล้มเหลว เพื่อให้คุณทดสอบได้ทั้งสองเส้นทาง
import { of, throwError } from 'rxjs';
apiSpy.getUser.and.returnValue(of({ name: 'Ada' })); // success
apiSpy.getUser.and.returnValue(throwError(() => new Error('boom'))); // erroruseClass สำหรับออบเจ็กต์จำลองที่นำกลับมาใช้ซ้ำได้
เมื่อออบเจ็กต์จำลองถูกใช้ซ้ำในสเปกหลายรายการ ให้กำหนด class และเชื่อมต่อด้วย useClass
class FakeUserApi {
getUser() { return of({ name: 'Test' }); }
}
TestBed.configureTestingModule({
providers: [{ provide: UserApi, useClass: FakeUserApi }],
});การจำลอง HttpClient ด้วย HttpTestingController
หากต้องการทดสอบบริการที่เรียกใช้ HTTP โดยไม่จำลองบริการทั้งชุด ให้นำเข้า provideHttpClientTesting() แล้วล้างคำขอผ่าน HttpTestingController
import { provideHttpClient } from '@angular/common/http';
import { provideHttpClientTesting, HttpTestingController } from '@angular/common/http/testing';
TestBed.configureTestingModule({
providers: [provideHttpClient(), provideHttpClientTesting()],
});การล้างคำขอ HTTP
คาดหวังคำขอ ตอบกลับด้วยข้อมูลจำลอง แล้วตรวจสอบว่าไม่มีการเรียกที่ไม่คาดคิดเหลืออยู่
const http = TestBed.inject(HttpTestingController);
service.load();
const req = http.expectOne('/api/users/7');
expect(req.request.method).toBe('GET');
req.flush({ name: 'Ada' });
http.verify();การแทนที่ Provider ต่อการทดสอบ
บางครั้งการทดสอบรายการหนึ่งต้องใช้ข้อมูลจำลองที่แตกต่างออกไป ให้ใช้ TestBed.overrideProvider() ก่อนเรียก createComponent
TestBed.overrideProvider(UserApi, {
useValue: { getUser: () => throwError(() => new Error('fail')) },
});
const fixture = TestBed.createComponent(ProfileComponent);จำลองเท่าที่จำเป็น
ตัวแทนจำลองที่ดีจะใช้เฉพาะเมธอดที่คอมโพเนนต์เรียกใช้จริงเท่านั้น การจำลองมากเกินไปทำให้การทดสอบผูกติดกับรายละเอียดภายใน ส่วนการจำลองน้อยเกินไปจะทำให้ผลข้างเคียงจริงรั่วไหลออกมา ให้ตรงกับสัญญาสาธารณะที่คอมโพเนนต์ต้องพึ่งพา
สอดแนมเมธอดของบริการจริง
คุณสามารถเก็บบริการจริงไว้ แล้วสอดแนมเมธอดหนึ่งรายการด้วย spyOn(instance, 'method') ซึ่งมีประโยชน์เมื่อบริการส่วนใหญ่ไม่มีผลเสีย แต่ต้องดักจับการเรียกหนึ่งรายการ
const svc = TestBed.inject(AnalyticsService);
spyOn(svc, 'track');
fixture.componentInstance.onClick();
expect(svc.track).toHaveBeenCalledWith('click');ตรวจสอบอย่างรวดเร็ว
คุณจะทำให้ตัวจำลองตรวจสอบการเรียกและควบคุมค่าที่ส่งกลับได้อย่างไร
สรุปทบทวน
คุณแทนที่ทรัพยากรที่ต้องพึ่งพาจริงด้วยตัวแทนจำลองโดยใช้ useValue, useClass และสายลับของ Jasmine ส่งคืน Observable ด้วย of/throwError ทดสอบ HTTP ผ่าน HttpTestingController และแทนที่ Provider แยกตามข้อกำหนดการทดสอบ จำลองเฉพาะสัญญาที่คอมโพเนนต์ใช้งาน
คำถามที่พบบ่อย
บทเรียน “การจำลองบริการและสิ่งที่ต้องพึ่งพา” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การจำลองบริการและสิ่งที่ต้องพึ่งพา” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Angular Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Angular Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การจำลองบริการและสิ่งที่ต้องพึ่งพา”
จัดเตรียมออบเจ็กต์จำลองสำหรับการทดสอบผ่าน DI คุณปฏิบัติ Angular Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Angular Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Angular Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “การจำลองบริการและสิ่งที่ต้องพึ่งพา” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Angular Academy นี้ได้ไหม
ได้ บทเรียน Angular Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- TestBed และฟิกซ์เจอร์คอมโพเนนต์
- การทดสอบอินพุต เอาต์พุต และ DOM
- การจำลองบริการและสิ่งที่ต้องพึ่งพา
- การทดสอบ Signals และโค้ดอะซิงโครนัส