mercredi 10 février 2021

How to mock a dynamic interface/struct creation(created based on user code) in Test classes

I have a go application and am confused regarding a testing aspect of the same. In my main method I create objects of the dependencies/services and pass to the main service that performs all the operations (sqsClient)

These objects "sess", "s3Handler" and "sqsClient" I can easily mock in the test main class.

--- main method ----

sess := createAwsSession()
s3Handler := NewS3Handler(*bucketNamePtr, "s3data", sess)
sqsClient, err := NewSqsHandler(sess, *visibilityTimeoutPtr, *timeoutPtr, *queueNamePtr)
if err != nil {
    log.Error(err.Error())
    os.Exit(1)
}
sqsClient.Start(HandlerFunc(messageHandler), s3Handler)

However in my message handler function I have to create a object of Upstream system, that can be either Redis or MySql based on the input i receive from SQS message. Even the destination DNS/IP of the MySql is decided based on the content of SQS message.

------- messageHandler function--------

func messageHandler(msg string, s3 *S3Handler) error {

    msgDetail, dest, msgErr := extractMessageDetails(msg, s3.Bucket)
    path, err := s3.DownloadData(msgDetail.prefix)
    if err != nil {
        return err
    }
    hosts := NonEmpty(strings.Split(dest, ","))
    upstream := Upstream{msgDetail.scheme, msgDetail.table}
    var task Command

    // is the destination is other than redis, consider it a mysql host
    // (as mysql host dns can be many can't add all in switch)
    switch dest {
    case "redis":
        task = upstream.UploadToRedis()
    default:
        task = upstream.UploadToMysql(hosts)
    }
    taskError := task.execute(path)
    if taskError != nil {
        return taskError
    }
    markerFile := GetMarkerName(msgDetail.table)
    markerErr := s3.UploadMarker(markerFile)
    if markerErr != nil {
        return markerErr
    }
}

----- Upstream struct ------

type Upstream struct {
    scheme, table string
}

// Mysql upstream system
type Mysql struct {
    *Upstream
    servers []string
}

// Redis upstream system
type Redis struct {
    *Upstream
}

Now my question is: How do I mock the Upstream object in method "messageHandler", as I cannot pass this from main method, as it's not known at the start of the program?

Aucun commentaire:

Enregistrer un commentaire