package main
import "github.com/gocql/gocql"
var CassandraSession *gocql.Session
func getSelectQuery(ClientId, UID, UUID, tableName, selectColumns string, sess *gocql.Session) (*gocql.Query, error) {
selectQuery := fmt.Sprintf(qTamplate, selectColumns, tableName)
query := sess.Query(selectQuery, ClientId, UID).Consistency(gocql.One)
err = query.Exec()
if err != nil {
return query, err
}
return query, nil
}
func GetSeglistFromCassandra(reqId string, dataMap MapUserRequest) (models.IsInSegmentResponse, error) {
resutMap := models.IsInSegmentResponse{}
tableName := fmt.Sprintf("getter_%v", cid[len(cid) - 1])
cqlsh := CassandraSession
selectColums := "cohortid, is_deleted, cohortype"
selectQueryObj, err := getSelectQuery(dataMap.ClientId, dataMap.UID, dataMap.UUID, tableName, selectColums, cqlsh)
if err != nil {
return resutMap, err
}
var id, deleted, cohortType int
iter := selectQueryObj.Iter()
for iter.Scan(&id, &deleted, &cohortType) {
if deleted == 0 {
if cohortType == 3 || cohortType == 2 {
resutMap.ListId = append(resutMap.ListId, id)
} else {
resutMap.SegIds = append(resutMap.SegIds, id)
}
}
}
if err := iter.Close(); err != nil {
return resultMap, err
}
return resutMap, nil
}
How to write unit test case in golang for this function GetSeglistFromCassandra which is using gocql without connecting to actual database if we can mock the gocql session creation, queries and iteration with example?
In my opinion, there is no way to write a unit test except for making an interface for gocql
and its implementations. its implementations will be a wrapper struct for gocql
and a mock for test.
The reason why we should use an interface and its wrapper struct is gocql
provides their concrete types such as gocql.Session
.
I suggest my approach to you. For that, I make your codes more simpler to handle.
package mockgocql
import (
"fmt"
"github.com/gocql/gocql"
)
// SessionInterface allows gomock mock of gocql.Session
type SessionInterface interface {
Query(stmt string, values ...interface{}) QueryInterface
}
// QueryInterface allows gomock mock of gocql.Query
type QueryInterface interface {
Exec() error
Consistency(c gocql.Consistency) QueryInterface
}
func simpleGetSelectQuery(ClientId, UID, UUID, tableName, selectColumns string, sessionInterface SessionInterface) (QueryInterface, error) {
selectQuery := fmt.Sprintf(selectColumns, tableName)
query := sessionInterface.Query(selectQuery, ClientId, UUID, UID).Consistency(gocql.One)
err := query.Exec()
if err != nil {
return query, err
}
return query, nil
}
func simpleGetSeglistFromCassandra(cqlsh SessionInterface, reqId string) error {
selectColums := "cohortid, is_deleted, cohortype"
_, err := simpleGetSelectQuery("ClientId", "Uid", "Uuid", "tableName", selectColums, cqlsh)
if err != nil {
return err
}
return err
}
simpleGetSelectQuery
and simpleGetSeglistFromCassandra
SessionInterface
and QueryInterface
CassandraSession
should be injected as SessionInterface
in simpleGetSeglistFromCassandra
gocql
through these interfaces. For that, you should make its implementation, first.package mockgocql
import (
"fmt"
"github.com/gocql/gocql"
)
type SessionImpl struct {
session *gocql.Session
}
type QueryImpl struct {
query *gocql.Query
}
func (s *SessionImpl) Query(stmt string, values ...interface{}) QueryInterface {
query := s.session.Query(stmt, values)
return &QueryImpl{query: query}
}
func (q *QueryImpl) Exec() error {
return fmt.Errorf("test")
}
func (q *QueryImpl) Consistency(c gocql.Consistency) QueryInterface {
return q
}
gocql
gocql
features.package mockgocql
import (
"github.com/gocql/gocql"
)
type SessionMock struct {
}
type QueryMock struct {
}
func (s *SessionMock) Query(stmt string, values ...interface{}) QueryInterface {
return &QueryMock{}
}
func (q *QueryMock) Exec() error {
return nil
}
func (q *QueryMock) Consistency(c gocql.Consistency) QueryInterface {
return q
}
package mockgocql
import (
"testing"
"github.com/stretchr/testify/assert"
)
func Test_simpleGetSeglistFromCassandra(t *testing.T) {
mockCassandra := SessionMock{}
err := simpleGetSeglistFromCassandra(&mockCassandra, "test")
assert.NoError(t, err)
}
I found others' trials here. https://github.com/gocql/gocql/issues/415 It seems they do similar things but it can be helpful to you.