Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimanakah saya boleh melaksanakan aliran kerja yang sama menggunakan irama RegisterDelayedCallback dalam ujian unit?

Bagaimanakah saya boleh melaksanakan aliran kerja yang sama menggunakan irama RegisterDelayedCallback dalam ujian unit?

WBOY
WBOYke hadapan
2024-02-10 10:50:09638semak imbas

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

editor php Baicao memperkenalkan anda cara menggunakan irama RegisterDelayedCallback dalam ujian unit untuk melaksanakan aliran kerja yang sama. Dalam ujian unit, kita selalunya perlu mensimulasikan operasi tak segerak untuk memastikan ketepatan kod dalam pelbagai keadaan. irama RegisterDelayedCallback ialah alat berkuasa yang boleh membantu kami mensimulasikan fungsi panggil balik tertunda dalam ujian. Dengan menggunakan RegisterDelayedCallback, kami boleh mensimulasikan operasi tak segerak dengan mudah, memastikan ketepatan kod dalam pelbagai situasi, dan dapat menghasilkan semula dan menyelesaikan masalah yang mungkin berlaku. Dalam artikel ini, kami akan meneroka cara menggunakan irama RegisterDelayedCallback untuk melaksanakan aliran kerja yang sama untuk membantu anda ujian unit yang lebih baik.

Kandungan soalan

Adakah mungkin untuk menjalankan ujian unit menggunakan registerdelayedcallback yang melakukan aliran kerja irama yang sama?

Saya mempunyai kod berikut yang menjalankan aliran kerja dua kali, pelaksanaan pertama menyimpan token panggil balik dan pelaksanaan kedua mendapatkan semula token yang disimpan untuk melengkapkan aktiviti secara tidak segerak.

workflow.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())
}

Kod di atas tidak lengkap, ia tidak menyimpan token panggil balik dan aktiviti lengkap panggilan. Untuk tujuan menguji jujukan, saya hanya ingin melihat log aliran kerja bermula dan aktiviti bermula dua kali, tetapi saya tidak nampak itu. Selepas aliran kerja pertama dimulakan, jika tiada log aktif, ujian akan digantung sehingga tamat tempoh.

Apakah yang saya hilang atau adakah mungkin untuk melaksanakan aliran kerja yang sama dua kali seperti ini?

Penyelesaian

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

Terdapat kebuntuan di sini. Dapatkan kunci yang sama pada env 在回调运行时被锁定(请参阅 源代码)。并且回调想要在同一个 env 上执行工作流,这需要在 env (lihat kod sumber).

Mari cuba memecahkan kebuntuan dengan menjalankan panggilan balik dalam goroutine baharu:

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

Kini kami panik:

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

Pada masa ini, testworkflowenvironment tidak boleh menjalankan 2 aliran kerja bukan ibu bapa-anak. Lihat isu penjejakan tugas untuk mendayakan persekitaran aliran kerja ujian untuk menyokong ujian berbilang aliran kerja .

Seperti yang dicadangkan oleh mesej panik, anda perlu mencipta testworkflowenvironment baharu untuk melaksanakan aliran kerja lain (tetapi saya tidak pasti sama ada ia sesuai untuk kes penggunaan anda).

Atas ialah kandungan terperinci Bagaimanakah saya boleh melaksanakan aliran kerja yang sama menggunakan irama RegisterDelayedCallback dalam ujian unit?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam