package user import ( "context" "errors" "testing" "perms-system-server/internal/response" "perms-system-server/internal/testutil/ctxhelper" "perms-system-server/internal/testutil/mocks" "perms-system-server/internal/types" "github.com/go-sql-driver/mysql" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/zeromicro/go-zero/core/stores/sqlx" "go.uber.org/mock/gomock" ) // TC-0144: 唯一索引冲突消息(Insert层1062错误)——H-R17-1 后 CreateUser 把 Insert // 收进 SysUserModel.TransactCtx 闭包,mock 路径必须同步切到 TransactCtx + InsertWithTx, // 否则 gomock 在 "Unexpected call to Insert" 上就把契约保真性覆盖掉。 func TestCreateUser_Mock_InsertDuplicate1062(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() mockUser := mocks.NewMockSysUserModel(ctrl) mockUser.EXPECT().TransactCtx(gomock.Any(), gomock.Any()).DoAndReturn( func(ctx context.Context, fn func(context.Context, sqlx.Session) error) error { return fn(ctx, nil) }) mockUser.EXPECT().InsertWithTx(gomock.Any(), gomock.Any(), gomock.Any()). Return(nil, &mysql.MySQLError{Number: 1062, Message: "Duplicate entry 'dupuser' for key 'username'"}) svcCtx := mocks.NewMockServiceContext(mocks.MockModels{ User: mockUser, }) logic := NewCreateUserLogic(ctxhelper.SuperAdminCtx(), svcCtx) _, err := logic.CreateUser(&types.CreateUserReq{ Username: "dupuser", Password: "Pass123456", }) require.Error(t, err) var codeErr *response.CodeError require.True(t, errors.As(err, &codeErr)) assert.Equal(t, 409, codeErr.Code()) assert.Equal(t, "用户名已存在", codeErr.Error()) }