pashagolub / pgxmock

pgx mock driver for golang to test database interactions
Other
386 stars 49 forks source link

ExpectCopyFrom not working as expected #127

Closed gandarez closed 1 year ago

gandarez commented 1 year ago

Describe the bug Calling ExpectCopyFrom is not considering either table name and column names passed in.

To Reproduce Steps to reproduce the behavior:

func TestCopyFromBug(t *testing.T) {
    mock, _ := NewConn()
    defer func() {
        err := mock.ExpectationsWereMet()
                 if err != nil {
            t.Errorf("expectation were not met: %s", err)
                 }
    }()

    mock.ExpectCopyFrom("foo", []string{"bar"}).WillReturnResult(1)

    var rows [][]any
    rows = append(rows, []any{"baz"})

    _, err := mock.CopyFrom(context.Background(), pgx.Identifier{"foo"}, []string{"bar"}, pgx.CopyFromRows(rows))
    if err != nil {
        t.Errorf("unexpected error: %s", err)
    }
}

Error

--- FAIL: TestCopyFromBug (0.00s)
    /Users/gandarez/development/git/pashagolub/pgxmock/pgxmock_test.go:30: unexpected error: CopyFrom: table name '"foo"' was not expected, expected table name is 'foo'
    /Users/gandarez/development/git/pashagolub/pgxmock/pgxmock_test.go:19: expectation were not met: there is a remaining expectation which was not matched: ExpectedCopyFrom => expecting CopyFrom which:
          - matches table name: 'foo'
          - matches column names: '[bar]'

Expected behavior It should assert with success.

Additional context pgxmock/v2 v2.5.0

gandarez commented 1 year ago

The error happens when it's comparing the expected table name without sanitization. The table name at pgx is sanitized using this func.

Screenshot 2023-03-02 at 17 41 56

The possible fix is to also sanitize the expected table name like:

e.expectedTableName = `"` + strings.ReplaceAll(strings.ReplaceAll(expectedTableName, string([]byte{0}), ""), `"`, `""`) + `"`

Should I create a PR for that?

gandarez commented 1 year ago

no one?

pashagolub commented 1 year ago

It would be great if you can provide a working solution. I'm out of capacity at the moment. Thanks for understanding

pashagolub commented 1 year ago

This works for me:

func TestCopyFromBug(t *testing.T) {
    mock, _ := NewConn()
    defer func() {
        err := mock.ExpectationsWereMet()
        if err != nil {
            t.Errorf("expectation were not met: %s", err)
        }
    }()

    mock.ExpectCopyFrom(pgx.Identifier{"foo"}.Sanitize(), []string{"bar"}).WillReturnResult(1)

    var rows [][]any
    rows = append(rows, []any{"baz"})

    _, err := mock.CopyFrom(context.Background(), pgx.Identifier{"foo"}, []string{"bar"}, pgx.CopyFromRows(rows))
    if err != nil {
        t.Errorf("unexpected error: %s", err)
    }
}
gandarez commented 1 year ago

It just worked because you called Sanitize() on pgx identifier. Should it be expected to be called and known by the developer when writing the test?

pashagolub commented 1 year ago

Make sense. I will change the ExpectCopyFrom() definition to match the CopyFrom() method.

Thanks for pointing this out.