DATA-DOG / go-sqlmock

Sql mock driver for golang to test database interactions
Other
5.95k stars 404 forks source link

"Issue Testing Row Scan Error with go-sqlmock: Uncovered Error Handling in Repository Function #324

Closed Bangik closed 1 month ago

Bangik commented 9 months ago

Issue Description

Hi... I'm facing an issue in my Go application when using go-sqlmock for unit testing my database interactions. The problem arises when trying to simulate a row scan error using sql.ErrNoRows. Although I've set up the test case for such a scenario, it seems that the specific line of code within my repository function is not covered by the test, and I'm not sure why. I would appreciate any help or insights on how to properly handle this case.

Code Sample

I have a function in my repository like this:

func (r *vendorRepository) List() ([]model.Vendor, error) {
    rows, err := r.db.Query("SELECT id, name, address, phone FROM vendors")
    if err != nil {
        return nil, err
    }

    var vendors []model.Vendor
    for rows.Next() {
        var vendor model.Vendor
        if err := rows.Scan(&vendor.Id, &vendor.Name, &vendor.Address, &vendor.Phone); err != nil {
            return nil, err
        }
        vendors = append(vendors, vendor)
    }

    return vendors, nil
}

And here are the relevant test cases:

func (s *VendorRepositorySuite) TestListSuccess() {
    // ... (omitting setup for successful query)
}

func (s *VendorRepositorySuite) TestListFail() {
    // ... (omitting setup for simulating sql.ErrNoRows)
}

func (s *VendorRepositorySuite) TestListRowScanError() {
    // ... (omitting setup for simulating a row scan error)
}

Problem

The issue I'm encountering is that the specific code block where I check for errors during row scanning:

if err := rows.Scan(&vendor.Id, &vendor.Name, &vendor.Address, &vendor.Phone); err != nil {
    return nil, err
}

is not being covered by my tests, even though I have a test case (TestListRowScanError) specifically designed to simulate the error using sql.ErrNoRows. The other test cases (TestListSuccess and TestListFail) are working as expected, but I'm having trouble understanding why the row scan error is not being triggered.

Requested Help

I would greatly appreciate any guidance or suggestions on how to properly test and cover the specific scenario of a row scan error using go-sqlmock. If there's anything I'm missing in my test setup or if there's a better way to test this kind of situation, please let me know.

Thank you in advance for your help and insights!

diegommm commented 1 month ago

Hi @Bangik! Thank you for your great write up :heart: To test the scenario of Scan returning an error you can use the following approach:

rows := yourMock.NewRows(someColumns).RowError(atRowNumWillReturn, someErr)
yourMock.ExpectQuery(yourExpectedQueryString).WillReturnRows(rows)

Please, let me know if that helped you and feel free to reopen if you need any further help, cheers!