DATA-DOG / go-sqlmock

Sql mock driver for golang to test database interactions
Other
6.02k stars 406 forks source link

Is it possible to throw `all expectations were already fulfilled` error only on `mock.ExpectationsWereMet()` call? #251

Open JanPetr opened 3 years ago

JanPetr commented 3 years ago

Hello there! I have rather question than an issue. I have code similar to this one:

func (a *Smt) Bar() (string, error) {
    f, err := a.foo(id)
    if err != nil {
        originalErr := err

        err = a.DB.UpdateError(id, "operation foo failed")
        if err != nil {
            return "", fmt.Errorf("update err: %w", err)
        }

        return "", fmt.Errorf("foo: %w", originalErr)
    }
    // ...
}

I'd like to test that if the foo fails, the DB update passes correctly and I get an error from Bar() method.

However, if I don't specify mock.ExpectExec for the err = a.DB.UpdateError(id, "operation foo failed") line I get error all expectations were already fulfilled thrown by return "", fmt.Errorf("update err: %w", err) line. Considering that my test is correctly expecting error thrown by return "", fmt.Errorf("foo: %w", originalErr) line I get a false positive test pass.

Is it possible to configure sqlmock to not to throw error on performing unexpected query and then return error on mock.ExpectationsWereMet() call saying there was an unexpected query performed?

Thank you and thanks for all your work!

l3pp4rd commented 3 years ago
  1. Instead of writting this long enough message you can just have a look into the sqlmock code
  2. The abstraction I see in your code, is terrible to my understanding. Create repositories for your db actions (without any inheritance which is a sad mistake in any language)
  3. Sqlmock can’t queue errors. It will return one whenever something is not as expected
  4. In order to have correct unit tests you have to correctly setup the expectation for a.foo behavior if it has db action in there then you need to expect it and return an error as mocked db behavior and in that case since there is an error in a.foo then expectation for the other update has to be expected. Simple as that. Why are you asking for magic which would just cause a headache for anyone you will maintain your code