Creating tests for database models. My goal test all testCases in transactions. Uses "github.com/stretchr/testify/suite"
Closure use to create records in transaction. What do you think about this approach? This code works, but I think: may be there is a more efficient way. May be I should use another approach, advise me please. I am a newbie in golang )
type tcCreateAccount struct {
name string
errMsg string
closure func(p *CreateAccountParams, q *Queries)
params CreateAccountParams
}
func (tc *tcCreateAccount) setup(s *accountTestSuiteType, q *Queries) {
user := createRandomUser(s.T(), s.ctx, q)
exchange := createRandomExchange(s.T(), s.ctx, q)
name := fmt.Sprintf("%s account at %s exchange", user.FullName, exchange.Name)
tc.params.OwnerID = user.UserID
tc.params.ExchangeID = exchange.ExchangeID
tc.params.Name = name
}
type closureType func(p *CreateAccountParams, q *Queries)
func newCreateAccountTestCase(name, errMsg string, closures ...closureType) tcCreateAccount {
var closure closureType
if len(closures) > 0 {
closure = closures[0]
}
return tcCreateAccount{
name: name,
errMsg: errMsg,
params: CreateAccountParams{
ApiKey: gofakeit.BitcoinPrivateKey(),
ApiSecret: gofakeit.BitcoinPrivateKey(),
Passphrase: gofakeit.Password(true, true, true, true, true, 12),
},
closure: closure,
}
}
func (s *accountTestSuiteType) TestCreateAccount() {
testCases := make([]tcCreateAccount, 0, 20)
testCases = append(testCases, newCreateAccountTestCase("Create regular accout", ""))
testCases = append(testCases,
newCreateAccountTestCase(`Create accout without ApiKey`, ``, func(p *CreateAccountParams, q *Queries) {
p.ApiKey = ``
}))
testCases = append(testCases,
newCreateAccountTestCase(`Create accout without ApiSecret`, ``, func(p *CreateAccountParams, q *Queries) {
p.ApiSecret = ``
}))
testCases = append(testCases,
newCreateAccountTestCase(`Create accout without Passphrase`, ``, func(p *CreateAccountParams, q *Queries) {
p.Passphrase = ``
}))
testCases = append(testCases,
newCreateAccountTestCase(`Create accout without OwnerID`, `"account_owner_id" (SQLSTATE 23514)`,
func(p *CreateAccountParams, q *Queries) {
p.OwnerID = 0
}))
testCases = append(testCases,
newCreateAccountTestCase(`Create accout without ExchangeID`, `"account_exchange_id" (SQLSTATE 23514)`,
func(p *CreateAccountParams, q *Queries) {
p.ExchangeID = 0
}))
testCases = append(testCases,
newCreateAccountTestCase(`Create accout without Name`, `"account_name_length" (SQLSTATE 23514)`,
func(p *CreateAccountParams, q *Queries) {
p.Name = ``
}))
testCases = append(testCases,
newCreateAccountTestCase(`Create not unique account`, `"accounts_name_owner_id_exchange_id_idx" (SQLSTATE 23505)`,
func(p *CreateAccountParams, q *Queries) {
a := createRandomAccount(s.T(), s.ctx, q)
p.ExchangeID = a.ExchangeID
p.OwnerID = a.OwnerID
p.Name = a.Name
}))
testCases = append(testCases,
newCreateAccountTestCase(`Create accout with random OwnerID`, `"accounts_owner_id_fkey" (SQLSTATE 23503)`,
func(p *CreateAccountParams, q *Queries) {
p.OwnerID = randomID()
}))
testCases = append(testCases,
newCreateAccountTestCase(`Create accout with random ExchangeID`, `"accounts_exchange_id_fkey" (SQLSTATE 23503)`,
func(p *CreateAccountParams, q *Queries) {
p.ExchangeID = randomID()
}))
for _, tc := range testCases {
err := s.store.ExecTx(s.ctx, func(q *Queries) error {
tc.setup(s, q)
if tc.closure != nil {
tc.closure(&tc.params, q)
}
account, err := q.CreateAccount(s.ctx, tc.params)
if len(tc.errMsg) == 0 {
s.T().Logf("Success case: %s", tc.name)
s.Require().NoError(err)
s.Require().NotEmpty(account)
s.Require().Equal(tc.params.OwnerID, account.OwnerID)
s.Require().Equal(tc.params.ExchangeID, account.ExchangeID)
s.Require().Equal(tc.params.Name, account.Name)
s.Require().Equal(tc.params.ApiKey, account.ApiKey)
s.Require().Equal(tc.params.ApiSecret, account.ApiSecret)
s.Require().Equal(tc.params.Passphrase, account.Passphrase)
} else {
s.T().Logf("Fail case: %s", tc.name)
s.Require().Error(err)
s.Require().Empty(account)
s.Require().ErrorContains(err, tc.errMsg)
}
return errRollbackTX
})
s.Require().ErrorIs(err, errRollbackTX)
}
}```