Go语言changeEmail函数测试触发空指针异常求助
Go测试中changeEmail函数触发空指针解引用Panic
问题描述
运行Go测试时,TestChangeEmail测试用例执行失败,changeEmail函数触发空指针解引用的运行时panic。
测试代码
func TestChangeEmail(t *testing.T) { ctx := context.Background() InitTestContext(ctx) buf := bytes.Buffer{} enc := json.NewEncoder(&buf) enc.Encode(testProfile) // Create the request object with JWT req, err := http.NewRequestWithContext(ctx, "PUT", "http://localhost:8080/v1/profile/", &buf) if err != nil { t.Fatal(err) } // // 1) Create the initial profile const sqlSelectAll = `SELECT * FROM "profiles" WHERE email = $1 ORDER BY "profiles"."id" LIMIT 1` const sqlCreate = `INSERT INTO "profiles" ("created_at","updated_at","deleted_at","display_name","email","email_verified","id") VALUES ($1,$2,$3,$4,$5,$6,$7) RETURNING "id"` expected := sqlmock.NewRows([]string{"id", "display_name", "email"}).AddRow(testProfile.ID, testProfile.DisplayName, testProfile.Email) mock.ExpectQuery(regexp.QuoteMeta(sqlSelectAll)).WithArgs(testProfile.Email).WillReturnError(fmt.Errorf("not found")) mock.ExpectBegin() mock.ExpectQuery(regexp.QuoteMeta(sqlCreate)).WithArgs(anyTime{}, anyTime{}, nil, testProfile.DisplayName, testProfile.Email, testProfile.EmailVerified, sqlmock.AnyArg()).WillReturnRows(expected) mock.ExpectCommit() newEmail := "test-changed@gmail.com" // // 2) Change the initial profile's email const sqlUpdate = `UPDATE "profiles" SET "email"=$1 WHERE "email"=$2` mock.ExpectBegin() mock.ExpectExec(regexp.QuoteMeta(sqlUpdate)).WithArgs(newEmail, testProfile.Email).WillReturnResult(sqlmock.NewResult(0, 1)) mock.ExpectCommit() if err := executeAndValidateRequest(req, http.StatusCreated); err != nil { t.Error(err) } }
错误信息
--- FAIL: TestChangeEmail (0.00s) panic: runtime error: invalid memory address or nil pointer dereference [recovered] panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x2 addr=0x18 pc=0x102d2fc94]
堆栈跟踪
goroutine 4 [running]: testing.tRunner.func1.2({0x1050f65e0, 0x105512000}) /usr/local/go/src/testing/testing.go:1396 +0x1c8 testing.tRunner.func1() /usr/local/go/src/testing/testing.go:1399 +0x378 panic({0x1050f65e0, 0x105512000}) /usr/local/go/src/runtime/panic.go:884 +0x204 gitlab/developers/server/profile.changeEmail({0x105199db8, 0x14000341e80}, 0x14000374600) /Users/example/Documents/project/server/profile/handlers.go:75 +0x44 net/http.HandlerFunc.ServeHTTP(0x14000374500?, {0x105199db8?, 0x14000341e80?}, 0x0?) /usr/local/go/src/net/http/server.go:2109 +0x38 github.com/gorilla/mux.(*Router).ServeHTTP(0x1400015a480, {0x105199db8, 0x14000341e80}, 0x14000374400) /Users/example/go/pkg/mod/github.com/gorilla/mux@v1.8.0/mux.go:210 +0x19c gitlab/developers/server/profile.executeAndValidateRequest(0x14000247ce0?, 0x12?) /Users/example/Documents/project/server/profile/handlers_test.go:134 +0xbc gitlab/developers/server/profile.TestChangeEmail(0x14000156d00) /Users/example/Documents/project/server/profile/handlers_test.go:282 +0x89c testing.tRunner(0x14000156d00, 0x105191b28) /usr/local/go/src/testing/testing.go:1446 +0x10c created by testing.(*T).Run /usr/local/go/src/testing/testing.go:1493 +0x300 FAIL gitlab/developers/server/profile 0.145s FAIL
问题分析与修复方向
- 核心定位:panic发生在
handlers.go第75行的changeEmail函数中,说明该行代码尝试解引用一个nil指针。 - 关键疑点:
- 测试代码中注释了"Create the request object with JWT"但未实际添加JWT头,导致后端无法解析出用户身份信息,
changeEmail函数中访问用户对象字段时触发nil解引用。 changeEmail函数中可能存在未做nil判断的变量,比如从请求上下文获取的用户对象、数据库操作返回的结果等。- SQL mock的预期是否与实际代码逻辑匹配,比如实际
changeEmail是否依赖前置查询,而mock未覆盖该路径导致代码进入错误分支。
- 测试代码中注释了"Create the request object with JWT"但未实际添加JWT头,导致后端无法解析出用户身份信息,
- 修复步骤:
- 给测试请求添加有效JWT头,示例:
其中req.Header.Set("Authorization", "Bearer "+testJWTToken)testJWTToken是预先生成的测试用有效token。 - 检查
handlers.go第75行代码,确认nil指针来源,添加nil判断或确保变量初始化完成。 - 验证SQL mock语句与实际执行的SQL完全一致,避免因不匹配导致代码执行未预期路径。
- 给测试请求添加有效JWT头,示例:
内容的提问来源于stack exchange,提问作者Buluc-Chabtan
相关产品推荐
相关产品推荐

