sqlmock с гормом ВСТАВИТЬ - PullRequest
0 голосов
/ 04 мая 2018

У меня много проблем с издевательством запросов INSERT. При выборе штрафа мне удалось пройти мои тесты, но при вставке я сталкиваюсь с этой ошибкой.

# gorms's debug output
INSERT INTO "groups" ("created_at","updated_at","deleted_at","name","description") VALUES ('2018-05-01 17:46:15','2018-05-01 17:46:15',NULL,'Group 1','A good group') RETURNING "groups"."id"

# Error returned from *gorm.DB.Create
2018/05/01 17:46:15 Error creating group: call to Query 'INSERT INTO "groups" ("created_at","updated_at","deleted_at","name","description") VALUES ($1,$2,$3,$4,$5) RETURNING "groups"."id"' with args [{Name: Ordinal:1 Value:2018-05-01 17:46:15.384319544 -0700 PDT m=+0.005382104} {Name: Ordinal:2 Value:2018-05-01 17:46:15.384319544 -0700 PDT m=+0.005382104} {Name: Ordinal:3 Value:<nil>} {Name: Ordinal:4 Value:Group 1} {Name: Ordinal:5 Value:A good group}], was not expected, next expectation is: ExpectedExec => expecting Exec or ExecContext which:
  - matches sql: '^INSERT INTO "groups" (.+)$'
  - is with arguments:
    0 - {}
    1 - {}
    2 - <nil>
    3 - Group 1
    4 - A good group
  - should return Result having:
      LastInsertId: 1
      RowsAffected: 1

Я пробовал несколько разных версий регулярного выражения, даже проверял совпадение с использованием golang на regex101.com, но я не могу заставить свой sqlmock соответствовать вставке Горм.

Вот мой тест:

type AnyTime struct{} // I don't actually know if I even need this

func (a AnyTime) Match(v driver.Value) bool {
    _, ok := v.(time.Time)
    return ok
}

func TestGroupService_Create(t *testing.T) {
    db, mock, err := sqlmock.New()
    if err != nil {
        log.Fatalf("can't create sqlmock: %s", err)
    }
    models.DB, err = gorm.Open("postgres", db)
    if err != nil {
        log.Fatalf("can't open gorm connection: %s", err)
    }
    defer db.Close()

    models.DB.LogMode(true)

    name := "Group 1"
    description := "A good group"

    mock.ExpectExec("^INSERT INTO \"groups\" (.+)$").WithArgs(AnyTime{}, AnyTime{}, nil, name, description).WillReturnResult(sqlmock.NewResult(1, 1))

    s := GroupService{}

    req := &pb.CreateGroupRequest{
        Name: name,
        Description: description,
    }

    resp, err := s.Create(context.Background(), req)
    assert.Nil(t, err)

    if assert.NotNil(t, resp) {
        assert.Equal(t, resp.Group.Name, name)
        assert.Equal(t, resp.Group.Description, description)
    }

    err = mock.ExpectationsWereMet()
    assert.Nil(t, err)
}

и мой метод обслуживания, который я пытаюсь проверить:

func (server *GroupService) Create(ctx context.Context, request *pb.CreateGroupRequest) (*pb.CreateGroupReply, error) {
    var group models.Group

    group.Name = request.Name
    group.Description = request.Description

    db := models.DB

    if err := db.Create(&group).Error; err != nil {
        log.Printf("Error creating group: %v", err)
        return nil, err
    }

    createReply := pb.CreateGroupReply{
        Group: mapGroupToService(group),
    }

    return &createReply, nil
}

Я просто не могу понять это. Спасибо!

1 Ответ

0 голосов
/ 04 мая 2018

Мне удалось смоделировать и вставить, переключившись на библиотеку go-mocket . Вроде бы сделано специально для ГОРМ. Я хотел бы знать, почему вставка sqlmock не работает, но это мое решение на данный момент:

func SetupTests() *gorm.DB {
    mocket.Catcher.Register()

    db, err := gorm.Open(mocket.DRIVER_NAME, "")
    if err != nil {
        log.Fatalf("error mocking gorm: %s", err)
    }
    // Log mode shows the query gorm uses, so we can replicate and mock it
    db.LogMode(true)
    models.DB = db

    return db
}

func TestGroupService_Create(t *testing.T) {
    db := SetupTests()
    defer db.Close()

    var mockedId int64 = 64
    mocket.Catcher.Reset().NewMock().WithQuery("INSERT INTO \"groups\"").WithId(mockedId)

    s := GroupService{}

    name := "Group 1"
    description := "A good group"

    req := &pb.CreateGroupRequest{
        Name: name,
        Description: description,
    }

    resp, err := s.Create(context.Background(), req)
    assert.Nil(t, err)

    if assert.NotNil(t, resp) {
        assert.Equal(t, uint32(mockedId), resp.Group.Id)
        assert.Equal(t, name, resp.Group.Name)
        assert.Equal(t, description, resp.Group.Description)
    }
}
...