Skip to content

Testing Functions

Chris O'Hara edited this page Jul 2, 2024 · 1 revision

Unit testing

A dispatchtest.Run function is provided for unit testing functions and workflows.

In this guide, we'll write a unit test for the following workflow:

var stringify = dispatch.Func("stringify", func(ctx context.Context, n int) (string, error) {
    return strconv.Itoa(n), nil
})

var double = dispatch.Func("double", func(ctx context.Context, n int) (int, error) {
    return n * 2, nil
})

var doubleAndRepeat = dispatch.Func("double-repeat", func(ctx context.Context, n int) (string, error) {
    doubled, err := double.Await(n)
    if err != nil {
        return "", err
    }
    stringified, err := stringify.Await(doubled)
    if err != nil {
        return "", err
    }
    return strings.Repeat(stringified, doubled), nil
})

First, build a Runner instance to orchestrate function execution:

runner := dispatchtest.NewRunner(doubleAndRepeat, double, stringify)

Next, run the workflow and collect the output:

output, err := dispatchtest.Call(runner, doubleAndRepeat, 4)
if err != nil {
    t.Fatal(err)
}

Finally, check the output is as expected:

if want := "88888888"; output != want {
    t.Errorf("unexpected output: got %q, want %q", output, want)
}

Here's the complete unit test, converted to a table-driven style so that it's easy to add new test cases:

func TestDoubleAndRepeat(t *testing.T) {
    runner := dispatchtest.NewRunner(doubleAndRepeat, double, stringify)

    for _, test := range []struct {
        input int
        want  string
    }{
        {
            input: 0,
            want:  "",
        },
        {
            input: 1,
            want:  "22",
        },
        {
            input: 2,
             want:  "4444",
        },
        {
            input: 3,
            want:  "666666",
        },
        {
            input: 4,
            want:  "88888888",
        },
    } {
        t.Run(test.want, func(t *testing.T) {
            output, err := dispatchtest.Call(runner, doubleAndRepeat, test.input)
            if err != nil {
                t.Fatal(err)
            } else if output != test.want {
                t.Errorf("unexpected output: got %q, want %q", output, test.want)
            }
        })
    }
}
Clone this wiki locally