Skip to content

Commit e895465

Browse files
authored
Merge pull request #183 from cschleiden/cschleiden/export-activity-state
Support testing activities
2 parents 249b879 + 8a05eff commit e895465

File tree

4 files changed

+89
-0
lines changed

4 files changed

+89
-0
lines changed

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,8 @@ workflow.Select(
486486

487487
### Unit testing
488488

489+
#### Workflows
490+
489491
go-workflows includes support for testing workflows, a simple example using mocked activities:
490492

491493
```go
@@ -514,6 +516,27 @@ func TestWorkflow(t *testing.T) {
514516
- Timers are automatically fired by advancing a mock workflow clock that is used for testing workflows
515517
- You can register callbacks to fire at specific times (in mock-clock time). Callbacks can send signals, cancel workflows etc.
516518

519+
#### Activities
520+
521+
Activities can be tested like any other function. If you make use of the activity context, for example, to retrieve a logger, you can use `activitytester.WithActivityTestState` to provide a test activity context. If you don't specify a logger, the default logger implementation will be used.
522+
523+
524+
```go
525+
func Activity(ctx context.Context, a int, b int) (int, error) {
526+
activity.Logger(ctx).Debug("Activity is called", "a", a)
527+
528+
return a + b, nil
529+
}
530+
531+
func TestActivity(t *testing.T) {
532+
ctx := activitytester.WithActivityTestState(context.Background(), "activityID", "instanceID", nil)
533+
534+
r, err := Activity(ctx, 35, 12)
535+
require.Equal(t, 47, r)
536+
require.NoError(t, err)
537+
}
538+
```
539+
517540
### Logging
518541
519542
For logging, you can pass a type to the backend via the `WithLogger` option to set a custom logger. The type has to implement this simple interface:

activitytester/activitytester.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package activitytester
2+
3+
import (
4+
"context"
5+
6+
"github.com/cschleiden/go-workflows/internal/activity"
7+
"github.com/cschleiden/go-workflows/internal/core"
8+
dlogger "github.com/cschleiden/go-workflows/internal/logger"
9+
"github.com/cschleiden/go-workflows/log"
10+
)
11+
12+
func WithActivityTestState(ctx context.Context, activityID, instanceID string, logger log.Logger) context.Context {
13+
if logger == nil {
14+
logger = dlogger.NewDefaultLogger()
15+
}
16+
17+
return activity.WithActivityState(ctx, activity.NewActivityState(activityID, core.NewWorkflowInstance(instanceID, ""), logger))
18+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package activitytester
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/cschleiden/go-workflows/activity"
8+
"github.com/stretchr/testify/require"
9+
)
10+
11+
func Activity(ctx context.Context, a int, b int) (int, error) {
12+
activity.Logger(ctx).Debug("Activity is called", "a", a)
13+
14+
return a + b, nil
15+
}
16+
17+
func TestActivityTester(t *testing.T) {
18+
ctx := WithActivityTestState(context.Background(), "activityID", "instanceID", nil)
19+
20+
r, err := Activity(ctx, 35, 12)
21+
require.Equal(t, 47, r)
22+
require.NoError(t, err)
23+
}

tester/tester_activity_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package tester
22

33
import (
4+
"context"
45
"testing"
56
"time"
67

8+
"github.com/cschleiden/go-workflows/activity"
79
"github.com/cschleiden/go-workflows/workflow"
810
"github.com/stretchr/testify/mock"
911
"github.com/stretchr/testify/require"
@@ -103,3 +105,26 @@ func Test_ActivityRaceWithSignal(t *testing.T) {
103105
require.Equal(t, "signal", wr)
104106
tester.AssertExpectations(t)
105107
}
108+
109+
func Test_ActivityWithLogger(t *testing.T) {
110+
activity1 := func(ctx context.Context) (string, error) {
111+
activity.Logger(ctx).Debug("hello from test")
112+
113+
return "activity", nil
114+
}
115+
116+
wf := func(ctx workflow.Context) error {
117+
workflow.ExecuteActivity[string](ctx, workflow.DefaultActivityOptions, activity1).Get(ctx)
118+
119+
return nil
120+
}
121+
122+
tester := NewWorkflowTester[string](wf, WithTestTimeout(time.Second*3))
123+
124+
tester.Registry().RegisterActivity(activity1)
125+
126+
tester.Execute()
127+
128+
require.True(t, tester.WorkflowFinished())
129+
tester.AssertExpectations(t)
130+
}

0 commit comments

Comments
 (0)