It’s already the 3rd day I’m thinking about this problem but without any solution.
I need to unit test my Tx manager - check that in all combinations rollback() and commit() methods all called in proper sequence.
sql.DB has the method BeginTx which returns sql.Tx. It returns a final type, not an interface (according to Go - pass interfaces and return types).
But in this case it’s not possible to return mock from BeginTx call - because even if we return mocked Tx-interface it has a different type!
I tested it in some hacky way - I just changed sql.DB mock to return Tx interface instead of final type, and tested against it, but now it needs to integrate test into production code.
I don’t want to make some wrappers on sql.DB in production code just to make unit tests working, but what are other solutions???
And why is it a standard in Go to return types instead of interfaces?
It makes testing harder!
Dependency injection is the way to go.
sql.BeginTxreturns a concrete type, but everywhere you pass the transaction, you should depend on a transaction interface rather than the type.e.g.
Now you can inject a mock transaction rather than the real
sql.Txanywhere as long as your mock satisfies the same type. For testing, your mock could then record calls to the transaction which you can verify.