测试与集成
本课属于 Coddy GO 学习旅程的“面向对象编程”单元。第 104 课,共 107 课。
挑战
简单让我们通过编写测试来验证一切是否正常,让图书管理系统的整个流程完整闭环!你将创建一个测试文件,用来验证图书馆的核心功能:确保图书可以正常借出和归还,并且错误情况也能得到正确处理。
你需要把代码分成 5 个文件:
book.go:定义包含ID、Title、Author、ISBN和Available字段的Book结构体。还要包含NewBook构造函数,将图书初始化为可借状态。user.go:定义包含ID、Name、Email和BorrowedBooks字段的User结构体。还要包含NewUser构造函数。library.go:定义包含图书和用户映射的Library结构体,以及NewLibrary、AddBook、AddUser、Borrow和Return方法。对于无效用户、无效图书或不可借的图书,Borrow方法应返回错误。对于无效用户、无效图书或未借出的图书,Return方法应返回错误。library_test.go:在这里编写测试函数!创建测试来验证:TestBorrowSuccess:验证借出可借图书成功(未返回错误)、图书变为不可借状态,并且图书 ID 已添加到用户的借阅列表中TestBorrowUnavailable:验证借出一本已被借出的图书时会返回错误TestBorrowInvalidUser:验证使用不存在的用户 ID 借书时会返回错误TestReturnSuccess:验证归还已借出的图书成功、图书重新变为可借状态,并且图书 ID 已从用户的借阅列表中移除
每个测试都应创建自己的图书馆,并添加所需的图书和用户,执行操作,然后在断言失败时使用
t.Error或t.Errorf检查结果。main.go:手动运行测试并报告结果。读取要执行的测试名称(borrow_success、borrow_unavailable、borrow_invalid_user或return_success)。根据测试名称设置相应的场景,如果所有断言都通过,就打印PASS;如果有任何断言失败,就打印FAIL: [reason]。
系统会提供以下输入:
- 一个测试名称:
borrow_success、borrow_unavailable、borrow_invalid_user或return_success
每个测试都使用以下标准测试数据:
- 图书:ID 为
B001,书名为Go Programming,作者为John Doe,ISBN 为123-456 - 用户:ID 为
U001,姓名为Alice,邮箱为alice@test.com
例如,输入:
borrow_success输出应为:
PASS输入:
borrow_unavailable输出应为:
PASS输入:
borrow_invalid_user输出应为:
PASS输入:
return_success输出应为:
PASS对于 borrow_success:创建图书馆,添加图书和用户,借出图书,验证没有错误、图书不可借,并且用户的借阅列表中包含这本图书。
对于 borrow_unavailable:创建图书馆,添加图书和用户,将图书的 Available 设为 false,尝试借书,并验证返回了错误。
对于 borrow_invalid_user:创建图书馆,只添加图书(不添加用户),使用用户 ID U001 尝试借书,并验证返回了错误。
对于 return_success:创建图书馆,添加图书和用户,先借出图书,再归还图书,验证没有错误、图书重新变为可借状态,并且用户的借阅列表为空。
编写测试可以确保图书馆系统正常运行,也能让你放心地进行修改,而不必担心破坏现有功能!
亲手试试
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
testName, _ := reader.ReadString('\n')
testName = strings.TrimSpace(testName)
// 标准测试数据
// 图书:ID "B001",书名 "Go Programming",作者 "John Doe",ISBN "123-456"
// 用户:ID "U001",姓名 "Alice",邮箱 "alice@test.com"
switch testName {
case "borrow_success":
// TODO:测试借阅可借图书是否成功
// 1. 创建图书馆,添加图书和用户
// 2. 借阅这本书
// 3. 验证:没有错误,图书不可借,用户的列表中有这本书
// 如果全部通过,输出 "PASS";如果有任何一项失败,输出 "FAIL: [reason]"
fmt.Println("FAIL: not implemented")
case "borrow_unavailable":
// TODO:测试借阅不可借的图书是否返回错误
// 1. 创建图书馆,添加图书和用户
// 2. 将图书的 Available 设置为 false
// 3. 尝试借阅
// 4. 验证是否返回错误
fmt.Println("FAIL: not implemented")
case "borrow_invalid_user":
// TODO: 测试使用无效用户借书时是否返回错误
// 1. 创建库,只添加图书(不添加用户)
// 2. 尝试使用用户 ID "U001" 借书
// 3. 验证是否返回错误
fmt.Println("FAIL: not implemented")
case "return_success":
// TODO: 测试归还已借出的图书是否成功
// 1. 创建图书馆,添加图书和用户
// 2. 先借出图书
// 3. 归还图书
// 4. 验证:没有错误,图书可借,用户的列表为空
fmt.Println("FAIL: not implemented")
default:
fmt.Println("FAIL: unknown test")
}
}
面向对象编程中的所有课
自己练习: Go 在线编译器