การทดสอบโมเดลมุมมอง
ทดสอบตรรกะการนำเสนอแบบหน่วยโดยแยกออกจากส่วนอื่น
การทดสอบโมเดลมุมมอง เป็นบทเรียน Swift Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Swift Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน
เหตุใดจึงต้องทดสอบ ViewModel
ViewModel เก็บตรรกะการนำเสนอของคุณไว้ จึงเป็นชั้นที่มีคุณค่ามากที่สุดสำหรับการทดสอบหน่วย เนื่องจากไม่มีการพึ่งพา UIKit หรือ SwiftUI คุณจึงสามารถทดสอบได้ โดยแยกเป็นอิสระ อย่างรวดเร็วและได้ผลลัพธ์แน่นอน
ออกแบบมาให้ทดสอบได้
ViewModel ที่สร้างมาอย่างดีจะรับสิ่งที่ต้องพึ่งพาผ่านตัวสร้าง การทำเช่นนี้ทำให้การทดสอบแทนที่สิ่งเหล่านั้นด้วยตัวจำลองได้
final class WeatherViewModel: ObservableObject {
@Published var temperatureText = ""
private let service: WeatherService
init(service: WeatherService) {
self.service = service
}
}การฉีดสิ่งที่ต้องพึ่งพา
ซ่อนสิ่งที่ต้องพึ่งพารูปธรรมไว้เบื้องหลัง โพรโทคอล ViewModel จะพึ่งพานามธรรม ทำให้การทดสอบสามารถฉีด mock ได้
protocol WeatherService {
func fetchTemperature() async throws -> Double
}เขียน mock
mock นำโพรโทคอลไปใช้และส่งคืนข้อมูลที่เตรียมไว้ ทำให้คุณควบคุมได้อย่างแม่นยำว่า ViewModel จะเห็นอะไร
final class MockWeatherService: WeatherService {
var stubbedTemperature: Double = 20
var didCallFetch = false
func fetchTemperature() async throws -> Double {
didCallFetch = true
return stubbedTemperature
}
}การทดสอบหน่วยพื้นฐาน
เมื่อฉีด mock เข้าไปแล้ว คุณจะตรวจสอบได้ว่า ViewModel แปลงข้อมูลได้อย่างถูกต้อง
func testFormatsTemperature() async {
let mock = MockWeatherService()
mock.stubbedTemperature = 25
let vm = WeatherViewModel(service: mock)
await vm.load()
XCTAssertEqual(vm.temperatureText, "25 C")
}ทดสอบการเปลี่ยนสถานะ
ViewModel มักเปิดเผยสถานะในรูปแบบ enum ให้ทดสอบแต่ละแขนงด้วยการป้อนข้อมูลที่ทำให้เกิดสถานะนั้น
func testLoadingThenLoaded() async {
let vm = FeedViewModel(service: MockFeedService())
XCTAssertEqual(vm.state, .loading)
await vm.load()
XCTAssertEqual(vm.state, .loaded(["A", "B"]))
}ทดสอบเส้นทางข้อผิดพลาด
ทำให้ mock โยนข้อผิดพลาดเพื่อยืนยันว่า ViewModel จัดการความล้มเหลวได้อย่างเหมาะสมและส่งต่อสถานะข้อผิดพลาด
final class FailingService: WeatherService {
func fetchTemperature() async throws -> Double {
throw URLError(.notConnectedToInternet)
}
}
func testShowsErrorOnFailure() async {
let vm = WeatherViewModel(service: FailingService())
await vm.load()
XCTAssertEqual(vm.state, .error)
}ตรวจสอบการโต้ตอบ
บางครั้งสิ่งที่คุณสนใจคือสิ่งที่ต้องพึ่งพาถูก เรียกใช้ ไม่ใช่เพียงผลลัพธ์เท่านั้น แฟล็กสำหรับสอดส่องบน mock ช่วยให้คุณตรวจสอบพฤติกรรมได้
func testFetchIsCalled() async {
let mock = MockWeatherService()
let vm = WeatherViewModel(service: mock)
await vm.load()
XCTAssertTrue(mock.didCallFetch)
}ทดสอบผลลัพธ์ของ @Published
คุณสามารถสมัครรับค่าจากพร็อพเพอร์ตี @Published ด้วย Combine เพื่อเก็บค่าที่ส่งออกมาและตรวจสอบลำดับของค่า
var received: [String] = []
let cancellable = vm.$temperatureText.sink { received.append($0) }
await vm.load()
XCTAssertEqual(received.last, "25 C")
cancellable.cancel()ทำให้การทดสอบรวดเร็ว
เนื่องจาก mock ส่งค่ากลับทันทีและไม่มีเครือข่ายจริง การทดสอบ ViewModel จึงทำงานเสร็จในระดับ milliseconds หลีกเลี่ยงตัวจับเวลาจริงและ URLSession — ให้ฉีดตัวจำลองสำหรับนาฬิกาและตัวจัดตารางเวลาด้วย
แนวทางปฏิบัติที่ดี
การทดสอบ ViewModel ที่มีประสิทธิภาพ:
- ฉีดสิ่งที่ต้องพึ่งพาทั้งหมดผ่านโพรโทคอล
- ทดสอบพฤติกรรมหนึ่งอย่างต่อหนึ่งเมธอดทดสอบ
- ครอบคลุมเส้นทางสำเร็จ ว่างเปล่า และข้อผิดพลาด
- ตรวจสอบผลลัพธ์ที่เผยแพร่ซึ่งมุมมองจะอ่าน
ตรวจสอบความเข้าใจ
ทดสอบความรู้เกี่ยวกับการทดสอบ ViewModel ของคุณ
สรุป
คุณได้เรียนรู้การทดสอบหน่วยของ ViewModel โดยแยกเป็นอิสระ:
- ฉีดสิ่งที่ต้องพึ่งพาไว้เบื้องหลังโพรโทคอล
- ใช้ mock เพื่อควบคุมข้อมูลป้อนเข้าและสอดส่องการเรียกใช้
- ครอบคลุมสถานะสำเร็จ ข้อผิดพลาด และว่างเปล่า
- ตรวจสอบผลลัพธ์
@Publishedและการเปลี่ยนสถานะ
ViewModel ที่ทดสอบได้คือผลลัพธ์จากการแยกหน้าที่ของ MVVM
คำถามที่พบบ่อย
บทเรียน “การทดสอบโมเดลมุมมอง” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การทดสอบโมเดลมุมมอง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Swift Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การทดสอบโมเดลมุมมอง”
ทดสอบตรรกะการนำเสนอแบบหน่วยโดยแยกออกจากส่วนอื่น คุณปฏิบัติ Swift Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Swift Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Swift Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “การทดสอบโมเดลมุมมอง” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Swift Academy นี้ได้ไหม
ได้ บทเรียน Swift Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- รูปแบบ MVVM
- การผูกโมเดลมุมมองเข้ากับมุมมอง
- รูปแบบ Coordinator
- การทดสอบโมเดลมุมมอง