Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues with new NamedArgs mocks #167

Closed
FryDay opened this issue Oct 31, 2023 · 7 comments · Fixed by #169
Closed

Issues with new NamedArgs mocks #167

FryDay opened this issue Oct 31, 2023 · 7 comments · Fixed by #169
Assignees
Labels
wontfix This will not be worked on

Comments

@FryDay
Copy link

FryDay commented Oct 31, 2023

Describe the bug
I'm trying to test an update command (via Exec) using pgx.NamedArgs, but ExpectExec does not seem to be doing the rewrite.

To Reproduce

	update := `
UPDATE "user"
SET email = @email,
    password = @password,
	pin = @pin,
	name = @name,
	software_admin = @software_admin,
	refresh_token = @refresh_token,
	updated_utc = @updated_utc
WHERE id = @id`

mock.ExpectExec(update).WithArgs(pgx.NamedArgs{
		"id":             mockUser.ID,
		"email":          mockUser.Email,
		"password":       mockUser.Password,
		"pin":            mockUser.Pin,
		"name":           mockUser.Name,
		"software_admin": mockUser.SoftwareAdmin,
		"refresh_token":  mockUser.RefreshToken,
		"updated_utc":    postgresql.AnyTime{},
	})

_, err := mock.Exec(context.Background(), update, pgx.NamedArgs{
		"id":             mockUser.ID,
		"email":          mockUser.Email,
		"password":       mockUser.Password,
		"pin":            mockUser.Pin,
		"name":           mockUser.Name,
		"software_admin": mockUser.SoftwareAdmin,
		"refresh_token":  mockUser.RefreshToken,
		"updated_utc":    time.Now().UTC(),
	})

I've removed a lot of the abstractions my application uses, but this is the jist of it. In this case, I get the following errors:

Error:      	Received unexpected error:
        	            	actual sql: "UPDATE "user" SET email = $1, password = $2, pin = $3, name = $4, software_admin = $5, refresh_token = $6, updated_utc = $7 WHERE id = $8" does not equal to expected "UPDATE "user" SET email = @email, password = @password, pin = @pin, name = @name, software_admin = @software_admin, refresh_token = @refresh_token, updated_utc = @updated_utc WHERE id = @id"

and

Error:      	Received unexpected error:
        	            	there is a remaining expectation which was not matched: ExpectedExec => expecting call to Exec():
        	            		- matches sql: '
        	            	UPDATE "user"
        	            	SET email = @email,
        	            	    password = @password,
        	            		pin = @pin,
        	            		name = @name,
        	            		software_admin = @software_admin,
        	            		refresh_token = @refresh_token,
        	            		updated_utc = @updated_utc
        	            	WHERE id = @id'
        	            		- is with arguments:
        	            			0 - map[email:[email protected] id:9007 name:Marta Wisozk password:$2a$12$w7fcJXeoPtPSGd1kM0u2fercPiBRlFUmCHDEcthECieb5MvGqdGGa pin:$2a$12$oJaaaqL9sOlt9BREnVAil.PMKFQCUIA6rRwY7aUo.pyBAJk79oHvS refresh_token:5dad961c-6a50-44da-94b2-88813f8eb3ea software_admin:false updated_utc:{}]

It's possible I'm just missing something, but as far as I can tell, this should work.

@pashagolub pashagolub self-assigned this Nov 2, 2023
@pashagolub pashagolub added the wontfix This will not be worked on label Nov 2, 2023
@FryDay
Copy link
Author

FryDay commented Nov 2, 2023

If it helps, the sql seems to get rewritten by argsMatches here. This seems like where the issue is coming from, but I'm not sure what the best way to fix it would be.

@pashagolub
Copy link
Owner

What is the definition of postgresql.AnyTime{}?

@FryDay
Copy link
Author

FryDay commented Nov 2, 2023

type AnyTime struct{}

// Match satisfies pgxmock.Argument interface
func (a AnyTime) Match(v interface{}) bool {
	_, ok := v.(time.Time)
	return ok
}

@pashagolub
Copy link
Owner

OK, I found the issue. In short: pgxmock always expects WithRewrittenSQL() for QueryRewriter arguments. Which is way too strict, I must agree. This works for me:

func TestFail(t *testing.T) {
	t.Parallel()
	mock, err := NewConn(QueryMatcherOption(QueryMatcherEqual))
	a := assert.New(t)
	a.NoError(err)

	update := `
UPDATE "user"
SET email = @email,
    password = @password,
	pin = @pin,
	name = @name,
	software_admin = @software_admin,
	refresh_token = @refresh_token,
	updated_utc = @updated_utc
WHERE id = @id`

	mock.ExpectExec(update).WithRewrittenSQL(`
UPDATE "user"
SET email = $1,
    password = $2,
	pin = $3,
	name = $4,
	software_admin = $5,
	refresh_token = $6,
	updated_utc = $7
WHERE id = $8`).WithArgs(pgx.NamedArgs{
		"id":             "mockUser.ID",
		"email":          "mockUser.Email",
		"password":       "mockUser.Password",
		"pin":            "mockUser.Pin",
		"name":           "mockUser.Name",
		"software_admin": "mockUser.SoftwareAdmin",
		"refresh_token":  "mockUser.RefreshToken",
		"updated_utc":    AnyArg(),
	}).WillReturnError(errPanic)

	_, err = mock.Exec(context.Background(), update, pgx.NamedArgs{
		"id":             "mockUser.ID",
		"email":          "mockUser.Email",
		"password":       "mockUser.Password",
		"pin":            "mockUser.Pin",
		"name":           "mockUser.Name",
		"software_admin": "mockUser.SoftwareAdmin",
		"refresh_token":  "mockUser.RefreshToken",
		"updated_utc":    time.Now().UTC(),
	})
	a.Error(err)
	a.NoError(mock.ExpectationsWereMet())
}

As you can see I specified both queries to expect: initial and rewritten. Let me try to fix it. I think it's not that complicated

Repository owner deleted a comment from FryDay Nov 2, 2023
@FryDay
Copy link
Author

FryDay commented Nov 2, 2023

I see, yeah, it almost feels backwards. If you manage to change it around, I'll be very happy!

@pashagolub
Copy link
Owner

Would you please try a fix in 167-fix-queryrewriter branch? This should work go get -u github.com/pashagolub/pgxmock/v3@167-fix-queryrewriter

@FryDay
Copy link
Author

FryDay commented Nov 2, 2023

Yes, that works perfectly! I tested it with both my Execs and my Queries.

pashagolub added a commit that referenced this issue Nov 2, 2023
[-] make sure `WithRewrittenSQL()` call is optional, fixes #167
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wontfix This will not be worked on
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants