首頁  >  文章  >  後端開發  >  如何在單元測試中使用 cadence RegisterDelayedCallback 執行相同的工作流程?

如何在單元測試中使用 cadence RegisterDelayedCallback 執行相同的工作流程?

WBOY
WBOY轉載
2024-02-10 10:50:09638瀏覽

如何在单元测试中使用 cadence RegisterDelayedCallback 执行相同的工作流程?

php小編百草為您介紹如何在單元測試中使用cadence RegisterDelayedCallback來執行相同的工作流程。在單元測試中,我們經常需要模擬非同步操作,以確保程式碼在各種情況下的正確性。 cadence RegisterDelayedCallback是一個強大的工具,它可以幫助我們在測試中模擬延遲的回調函數。透過使用RegisterDelayedCallback,我們可以輕鬆地模擬非同步操作,確保程式碼在各種情況下的正確性,並且能夠重現和修復潛在的問題。在本文中,我們將探討如何使用cadence RegisterDelayedCallback來執行相同的工作流程,以幫助您更好地進行單元測試。

問題內容

是否可以使用執行相同節奏工作流程的 registerdelayedcallback 執行單元測試?

我有以下程式碼運行工作流程兩次,第一次執行儲存回呼令牌,第二次執行檢索已儲存的令牌以非同步完成活動。

工作流程.go

package workflow

import (
    "context"
    "encoding/base64"
    "fmt"

    "go.uber.org/cadence/activity"
    "go.uber.org/cadence/workflow"
)

type workflowimpl struct {
    worker.worker
    client.client
}

func (w workflowimpl) tactivity(ctx context.context, action string) error {
    fmt.println("tactivity started", action)
    if action != "approved" {
        activityinfo := activity.getinfo(ctx)
        callbacktoken := base64.stdencoding.encodetostring(activityinfo.tasktoken)
        fmt.println("save callbacktoken", callbacktoken)
        // saves callbacktoken.

        return activity.errresultpending
    }

    fmt.println("approved")
    // do some approved things.
    // get saved callback token.
    // call w.completeactivity() with the saved callback token.
    return nil
}

func (w workflowimpl) tworkflow(ctx workflow.context, action string) (result string, err error) {
    fmt.println("tworkflow started", action)

    waitchannel := workflow.newchannel(ctx)
    workflow.go(ctx, func(ctx workflow.context) {
        if err := workflow.executeactivity(ctx, w.tactivity, action).get(ctx, nil); err != nil {
            // do nothing, keep workflow open.
            return
        }

        waitchannel.send(ctx, "ok")
    })

    var signal string
    waitchannel.receive(ctx, &signal)

    return signal, nil
}

workflow_test.go

package workflow_test

import (
    "time"
    "go.uber.org/cadence/worker"
)

func (s *UnitTestSuite) Test_TWorkflow() {
    env := s.NewTestWorkflowEnvironment()

    worker := workflow.WorkflowImpl{
         Worker: ...
         Client: ...
    }

    s.worker = &worker

    env.RegisterActivity(s.worker.TActivity)

    // Delay second TWorkflow.
    env.RegisterDelayedCallback(func() {
        env.ExecuteWorkflow(s.worker.TWorkflow, "Approved")
    }, time.Second*2)

    env.ExecuteWorkflow(s.worker.TWorkflow, "Noop")
    s.True(env.IsWorkflowCompleted())
    s.NoError(env.GetWorkflowError())
}

上面的程式碼並不完整,它沒有保存回調令牌並呼叫completeactivity。為了測試序列的目的,我只希望看到工作流程啟動的日誌和活動啟動兩次,但我沒有看到這一點。第一個工作流程啟動後,如果沒有任何活動的日誌,測試就會掛起直到逾時。

缺少什麼或是否可以像這樣執行相同的工作流程兩次?

解決方法

env.registerdelayedcallback(func() {
    env.executeworkflow(s.worker.tworkflow, "approved")
}, time.second*2)

這裡出現了僵局。 env 在回呼運行時被鎖定(請參閱 原始碼)。並且回呼想要在同一個 env 上執行工作流程,這需要在 env 上取得相同的鎖定(請參閱 原始程式碼)。

讓我們嘗試透過在新的 goroutine 中運行回調來打破僵局:

env.registerdelayedcallback(func() {
    go env.executeworkflow(s.worker.tworkflow, "approved")
}, time.second*2)

現在我們感到恐慌:

panic: Current TestWorkflowEnvironment is used to execute s.worker.TWorkflow. Please create a new TestWorkflowEnvironment for s.worker.TWorkflow.

目前,testworkflowenvironment 無法執行 2 個非父子工作流程。請參閱追蹤任務的問題以使 testworkflowenvironment 支援測試多個工作流程 .

正如恐慌訊息所建議的那樣,您必須建立一個新的 testworkflowenvironment 來執行另一個工作流程(但我不確定它是否適合您的用例)。

以上是如何在單元測試中使用 cadence RegisterDelayedCallback 執行相同的工作流程?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除