2

I am having problems comparing the query expected with the true query of gorm, this is my code:

package repository

import (
    "regexp"
    "testing"

    "github.com/DATA-DOG/go-sqlmock"
    "YOUR_GO_ROOT/pkg/domain"
    "github.com/stretchr/testify/assert"
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
)


var successGetTransaction domain.Transaction = domain.Transaction{
    ID:          2,
    BuyerID:     2,
    SellerID:    5,
    ItemID:      2,
    MessageID:   2,
    ExpiredDate: "2022-09-010 01:01:00",
    CreatedAt:   "2022-09-08 01:01:00",
}

func TestSuccessGetTransactionByID(t *testing.T) {

    db, mock, err := sqlmock.New()
    assert.NoError(t, err)
    gdb, err := gorm.Open(mysql.New(mysql.Config{
        Conn:                      db,
        SkipInitializeWithVersion: true,
    }), &gorm.Config{})
    assert.NoError(t, err)

    rows := sqlmock.NewRows([]string{"id", "buyer_id", "seller_id", "item_id", "message_id", "expired_date", "created_at"}).
        AddRow(2, 2, 5, 2, 2, "2022-09-010 01:01:00", "2022-09-08 01:01:00")
    mock.ExpectQuery(regexp.QuoteMeta("SELECT * FROM transaction WHERE id = ?;")).WillReturnRows(rows)

    repo := DefaultClient(gdb)
    actualSectionList, _ := repo.GetTransactionByID(2)
    
    assert.Equal(t, successGetTransaction, actualSectionList, "ambas listas deberian ser iguales")
    assert.NoError(t, mock.ExpectationsWereMet())
}

here is the module domain:

package domain

type Transaction struct {
    ID          int64  `gorm:"primaryKey;column:id"`
    BuyerID     int64  `gorm:"column:buyer_id"`
    SellerID    int64  `gorm:"column:seller_id"`
    ItemID      int    `gorm:"column:item_id"`
    MessageID   int    `gorm:"column:message_id"`
    ExpiredDate string `gorm:"column:expired_date"`
    CreatedAt   string `gorm:"column:created_at"`
}

func (Transaction) TableName() string {
    return "transaction"
}

type TransactionStatus struct {
    ID             int64  `gorm:"primaryKey;column:id"`
    TransactionID  int64  `gorm:"column:transaction_id"`
    Status         int    `gorm:"column:status"`
    NotificationID int    `gorm:"column:notification_id"`
    CreatedAt      string `gorm:"column:created_at"`
}

func (TransactionStatus) TableName() string {
    return "transaction_status"
}

and here the function that I am testing:

package repository

import (
    "fmt"

    "YOUR_GO_ROOT/pkg/domain"
    "gorm.io/gorm"
)

type RepositoryClient interface {
    GetTransactionByID(id int) (domain.Transaction, error)
}

type repositoryClient struct {
    db *gorm.DB
}

func DefaultClient(db *gorm.DB) RepositoryClient {
    return &repositoryClient{
        db: db,
    }
}

func (rc repositoryClient) GetTransactionByID(id int) (domain.Transaction, error) {
    trans := domain.Transaction{}
    status := rc.db.Where("id = ?", id).Find(&trans)

    if status.Error != nil {
        return domain.Transaction{}, status.Error
    }
    if trans == (domain.Transaction{}) {
        return domain.Transaction{}, fmt.Errorf("error finding transaction id %v", id)
    }
    return trans, nil
}

this is the error that I am getting from the console:

Query: could not match actual sql: "SELECT * FROM `transaction` WHERE id = ?" with expected regexp "SELECT \* FROM transaction WHERE id = \?;"[0m[33m[0.218ms] [34;1m[rows:0][0m SELECT * FROM `transaction` WHERE id = 2

in this seccion exist an answer that is substitute with "SELECT(.*)" but according to what i had read that is not a real solution

4
  • There are some differences between the actual query (the one that gorm generates) and your query. In your query, the transaction part is missing backticks (`) and there is also an extra semicolon (;) at the end. Try matching your query and the generated query to be exactly the same. Commented Dec 15, 2022 at 19:32
  • i tried that but didn't work, this is what i get : could not match actual sql: "SELECT * FROM `transaction` WHERE id = ?" with expected regexp "SELECT * FROM `transaction` WHERE id = ?" [0m[33m[0.360ms] [34;1m[rows:0][0m SELECT * FROM `transaction` WHERE id = 2 obviously to get that I had to take off the regexp.QuoteMeta function because that function escape some symbols and that cause the "\" symbole in the query Commented Dec 15, 2022 at 19:43
  • That specific case, where the test fails with that error but the actual and expected queries are the same, happens to me when I have this situation: I run multiple tests in one test suite, a test fails with some other error, all subsequent tests fail with that specific error (could not match the actual and expected queries, but the queries are the same). When I fix that test with an error, all other tests pass. Commented Dec 15, 2022 at 19:53
  • I have only this test, I don't have more test right now, you could copy all the code that I upload and see if this test run to you Commented Dec 15, 2022 at 20:25

1 Answer 1

1

Let me try to help to figure out the issue. I downloaded all of your files and the domain.go and the repository.go look fine to me.
However, I found some small issues in the repository_test.go file:

  1. Backticks missing in the SQL query you wrote
  2. An extra ; at the end of the query
  3. The invocation to the method WithArgs(2) is missing

If you adjusted these small issues you should have a code that looks like this one:

// ... omitted for brevity
func TestSuccessGetTransactionByID(t *testing.T) {
    db, mock, err := sqlmock.New()
    assert.NoError(t, err)
    gdb, err := gorm.Open(mysql.New(mysql.Config{
        Conn:                      db,
        SkipInitializeWithVersion: true,
    }), &gorm.Config{})
    assert.NoError(t, err)

    rows := sqlmock.NewRows([]string{"id", "buyer_id", "seller_id", "item_id", "message_id", "expired_date", "created_at"}).AddRow(2, 2, 5, 2, 2, "2022-09-010 01:01:00", "2022-09-08 01:01:00")
    mock.ExpectQuery(regexp.QuoteMeta("SELECT * FROM `transaction` WHERE id = ?")).WithArgs(2).WillReturnRows(rows)

    repo := DefaultClient(gdb)
    actualSectionList, _ := repo.GetTransactionByID(2)

    assert.Equal(t, successGetTransaction, actualSectionList, "ambas listas deberian ser iguales")
    assert.NoError(t, mock.ExpectationsWereMet())
}

Then, if you try to run the test it should work.
Let me know if this solves your issue, thanks!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.