Home > Back-end >  call to Rollback transaction, was not expected, next expectation is: ExpectedQuery
call to Rollback transaction, was not expected, next expectation is: ExpectedQuery

Time:07-05

I am trying to wrote this test bellow, other tests works fine, however I am having problems with the UPDATE query

func TestDeleteWorkspace(t *testing.T) {
    conn, mock, repository, err := setup()
    defer conn.Close()
    assert.NoError(t, err)

    uid := uuid.New()

    // mock.ExpectBegin()
    mock.ExpectQuery(regexp.QuoteMeta(`UPDATE "workspaces" SET`)).WithArgs(sqlmock.AnyArg(), uid)
    // mock.ExpectCommit()

    var e bool
    e, err = repository.Delete(uid)
    assert.NoError(t, err)
    assert.True(t, e)

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

repository.Delete does this query

func (r *WorkspaceRepository) Delete(id any) (bool, error) {
    if err := r.db.Delete(&model.Workspace{}, "id = ?", id).Error; err != nil {
        return false, nil
    }

    return true, nil
}

Which runs this query

UPDATE "workspaces" SET "deleted_at"='2022-07-04 09:09:20.778' WHERE id = 'c4610193-b43a-4ed7-9ed6-9d67b3f97502' AND "workspaces"."deleted_at" IS NULL

I am using Soft-Delete, that is why it is an UPDATE and not a DELETE query

However, I get the following error

    workspace_test.go:169: 
                Error Trace:    workspace_test.go:169
                Error:          Received unexpected error:
                                there is a remaining expectation which was not matched: ExpectedQuery => expecting Query, QueryContext or QueryRow which:
                                  - matches sql: 'UPDATE "workspaces" SET'
                                  - is with arguments:
                                    0 - 28e7aa46-7a22-4dc7-b3ce-6cf02af525ca
                                    1 - {}

What I am doing wrong?

EDIT: It is a soft-delete operation, that why is a UPDATE and not a DELETE

My model

type Workspace struct {
    ID        uuid.UUID      `gorm:"type:uuid;default:uuid_generate_v4()" json:"id"`
    Name      string         `gorm:"not null,type:text" json:"name"`
    CreatedAt time.Time      `gorm:"autoCreateTime" json:"create_time"`
    UpdatedAt time.Time      `gorm:"autoUpdateTime" json:"update_time"`
    DeletedAt gorm.DeletedAt `gorm:"index,->" json:"-"`
}

CodePudding user response:

Error message is quite self-explanatory.

This is your query:

'UPDATE "workspaces" SET "deleted_at"=$1 WHERE id = $2 AND "workspaces"."deleted_at" IS NULL'

it includes 2 arguments:

"deleted_at"=$1 WHERE id = $2

You set only 1 in your SQL mock:

.WithArgs(uid)

You need to send both arguments in mock.

It is not reliable to use Time.Now() in test because that value occasionally is going to be a few nanoseconds different from the value you set in code and test will fail.

The quick and dirty fix is to use sqlmock.AnyArg():

.WithArgs(sqlmock.AnyArg(), uid)

A more sophisticated alternative is to write custom Argument that checks type and compares value with time.Now(). Difference should be less than a few seconds.

See an example: https://github.com/DATA-DOG/go-sqlmock#matching-arguments-like-timetime

  • Related