1

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)
    }
}```



greenif
  • 1,055
  • 1
  • 12
  • 25

0 Answers0