如何为gocql编写单元测试用例

问题描述 投票:0回答:1
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
}

如果我们可以通过示例模拟 gocql 会话创建、查询和迭代,如何在 golang 中为使用 gocql 的 GetSeglistFromCassandra 函数编写单元测试用例,而无需连接到实际数据库?

go go-testing gocql
1个回答
0
投票

总结

在我看来,除了为

gocql
制作接口及其实现之外,没有其他方法可以编写单元测试。它的实现将是
gocql
的包装结构,或者用于测试的模拟。

我们应该使用接口和包装结构的原因是

gocql
提供它们的具体类型,例如
gocql.Session

我的建议

我向你建议我的方法。为此,我使您的代码更易于处理。

简单.go

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
      simpleGetSeglistFromCassandra
    • 接口
      SessionInterface
      QueryInterface
    • 并且
      CassandraSession
      应作为
      SessionInterface
      注入
      simpleGetSeglistFromCassandra
  • 从现在开始,您通过这些接口使用
    gocql
    。为此,你应该实施它

impl.go

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
    。它还可以进行模拟

mock.go

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
}
  • 变化
    • 这些代码是接口的模拟实现
  • 这是我们想要的模拟。我们可以在测试中根据需要进行任何模拟实现。

simple_test.go

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

  • 我们可以用模拟进行测试。
  • 如果我们想要各种场景的测试,我们可以根据场景进行mock。

参考

我在这里找到了其他人的试验。 https://github.com/gocql/gocql/issues/415 他们似乎做了类似的事情,但对你很有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.