1

我正在尝试测试一个获取一些详细信息然后在数据库中更新详细信息的函数。我正在为我的 ORM 使用 gorm,并使用 DATA-DOG/sqlmock 模拟 db exec。但是我不断收到预期的开始错误,但不确定我在哪里搞砸了。我尝试了许多代码变体,其中删除了 expectBegin expectCommit 等。

这是我要测试的代码:

// UpsertUserProfile saves the user if doesn't exists and adds the OAuth profile
// and updates existing user info if record exist in db
func (o *ORM) UpsertUserProfile(gu *goth.User) (*models.User, error) {
    db := o.DB
    up := &models.UserProfile{}
    u, err := models.GothUserToDBUser(gu, false)
    if err != nil {
        return nil, err
    }

    tx := db.Where("email = ?", gu.Email).First(u)
    if tx.Error != nil && tx.Error != gorm.ErrRecordNotFound {
        return nil, tx.Error
    }

    if tx := db.Model(u).Save(u); tx.Error != nil {
        return nil, tx.Error
    }

    tx = db.Where("email = ? AND provider = ? AND external_user_id = ?", gu.Email, gu.Provider, gu.UserID).First(up)
    if tx.Error != nil && tx.Error != gorm.ErrRecordNotFound {
        return nil, tx.Error
    }

    up, err = models.GothUserToDBUserProfile(gu, false)
    if err != nil {
        return nil, err
    }

    up.User = *u
    if tx := db.Model(up).Save(up); tx.Error != nil {
        return nil, tx.Error
    }
    return u, nil
}

这是测试代码

func TestORM_UpsertUserProfile(t *testing.T) {
    mockdb, mock, err := sqlmock.New()
    if err != nil {
        t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
    }
    gormDB, err := gorm.Open(postgres.New(postgres.Config{
        Conn: mockdb,
    }), &gorm.Config{})
    if err != nil {
        t.Fatal(err.Error())
    }
    defer mockdb.Close()

    id, _ := uuid.NewV4()

    rows := sqlmock.NewRows([]string{"id", "first_name", "last_name"}).
        AddRow(id.String(), "fname", "lname")
    profileRows := sqlmock.NewRows([]string{"email"}).AddRow("email")

    // Test cases
    t.Run("success", func(t *testing.T) {
        o := &ORM{
            DB: gormDB,
        }
        now := time.Now()
        fName := "fname"
        lName := "lname"
        wantUsr := models.User{
            Email:     "email",
            FirstName: &fName,
            LastName:  &lName,
            BaseModelSoftDelete: models.BaseModelSoftDelete{
                BaseModel: models.BaseModel{
                    ID:        id,
                    CreatedAt: &now,
                    UpdatedAt: &now,
                },
            },
        }

        mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "users"`)).WithArgs("email").WillReturnRows(rows)
        mock.ExpectBegin()
        mock.ExpectExec(regexp.QuoteMeta(`UPDATE`)).WillReturnResult(sqlmock.NewResult(1, 1))
        mock.ExpectCommit()
        mock.ExpectBegin()
        mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "user_profiles"`)).WithArgs("email", "provider", "testID").WillReturnRows(profileRows)
        mock.ExpectCommit()
        mock.ExpectBegin()

        got, err := o.UpsertUserProfile(&goth.User{Email: "email", UserID: "testID", Provider: "provider"})
        if (err != nil) != false {
            t.Errorf("ORM.UpsertUserProfile() error = %v, wantErr %v", err, false)
            return
        }
        if !reflect.DeepEqual(got, wantUsr) {
            t.Errorf("ORM.UpsertUserProfile() = %v, want %v", got, wantUsr)
        }
    })
}

但测试不断返回此错误

SELECT * FROM "user_profiles" WHERE email = 'email' AND provider = 'provider' AND external_user_id = 'testID' ORDER BY "user_profiles"."id" LIMIT 1
    /Users/public/Projects/go-rest-service/internal/orm/orm_test.go:260: ORM.UpsertUserProfile() error = call to Query 'SELECT * FROM "user_profiles" WHERE email = $1 AND provider = $2 AND external_user_id = $3 ORDER BY "user_profiles"."id" LIMIT 1' with args [{Name: Ordinal:1 Value:email} {Name: Ordinal:2 Value:provider} {Name: Ordinal:3 Value:testID}], was not expected, next expectation is: ExpectedBegin => expecting database transaction Begin, wantErr false
4

0 回答 0