# Unit testing timeouts

**URL:** <https://community.temporal.io/t/unit-testing-timeouts/5440>\
**Category:** Community Support\
**Tags:** go-sdk, testing\
**Created:** [July 22, 2022, 5:51pm UTC](https://community.temporal.io/t/unit-testing-timeouts/5440 "2022-07-22T17:51:24Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![ning](https://avatars.discourse-cdn.com/v4/letter/n/b5e925/32.png) [@ning](https://community.temporal.io/u/ning)\
**Post date:** [July 22, 2022, 5:51pm UTC](https://community.temporal.io/t/unit-testing-timeouts/5440/1 "2022-07-22T17:51:24Z")

</div>

Hi! I’m writing workflow unit tests and wondering if the Temporal experts here have any pointers on testing timeouts?  
The workflow will be part of a service that has an SLO, so before executing a child workflow, I set a timeout:

```auto
	workflowOptions := workflow.ChildWorkflowOptions{
		WorkflowExecutionTimeout: time.Hour * 24,
	}

```

I want to test that this timeout indeed fails the workflow when running too long. In my test, I set it up so that child workflow runs a loooong time

```auto
s.env.OnWorkflow(ParentWorkflow, mock.Anything, param).Return(nil).After(30 * 24 * time.Hour).Once()
s.True(s.env.IsWorkflowCompleted())
s.NoError(s.env.GetWorkflowError())

```

I’m expecting this test to fail with the workflow returning a timeout error. But the test passed?! What am I doing wrong here?

---

<div class="post-metadata">

**Author:** ![tihomir](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/tihomir/32/6580_2.png) [@tihomir](https://community.temporal.io/u/tihomir)\
**Post date:** [July 23, 2022, 2:30am UTC](https://community.temporal.io/t/unit-testing-timeouts/5440/2 "2022-07-23T02:30:57Z")

</div>

Test framework performs time skipping if a workflow is blocked so it allows unit tests to execute much much faster.

You could use RegisterDelayedCallback (sample [here](https://github.com/temporalio/samples-go/blob/main/query/query_workflow_test.go#L16)) to registers a callback to fire after a delay and perform your checks in this callback.

That said we should try to reproduce this so could make sure there isn’t and issue with WorkflowExecutionTimeout in SDK test suite. Could you share a reproduce and your Go SDK version used?

---

<div class="post-metadata">

**Author:** ![maxim](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/maxim/32/8_2.png) [@maxim](https://community.temporal.io/u/maxim)\
**Post date:** [July 23, 2022, 5:50pm UTC](https://community.temporal.io/t/unit-testing-timeouts/5440/3 "2022-07-23T17:50:37Z")

</div>

I filed an issue to fix [this](https://github.com/temporalio/sdk-go/issues/866).

---

<div class="post-metadata">

**Author:** ![ning](https://avatars.discourse-cdn.com/v4/letter/n/b5e925/32.png) [@ning](https://community.temporal.io/u/ning)\
**Post date:** [July 25, 2022, 6:27pm UTC](https://community.temporal.io/t/unit-testing-timeouts/5440/4 "2022-07-25T18:27:13Z")

</div>

Thank you tihomir! I was interested to know whether the issue was incorrect setup or that the timeouts are ignored in the test environment. Glad to have an answer 🙂  
I can probably do a manual testing to verify the timeout setup, but having a unit test would be much easier. Thanks maxim for filing the issue!  
I’m using Go version 1.18.4

Repro:  
Note that I made some changes to make the examples simpler but the results are the same.  
Test:

```auto
type TimeoutTestSuite struct {
	suite.Suite
	testsuite.WorkflowTestSuite
	env *testsuite.TestWorkflowEnvironment
}

func (s *TimeoutTestSuite) SetupTest() {
	s.env = s.NewTestWorkflowEnvironment()
	s.env.RegisterWorkflow(NoOp)
	s.env.RegisterActivity(NoopActivity2)
	s.env.RegisterWorkflow(NoOp2)
	s.env.RegisterWorkflow(NoopChild)
}

func (s *TimeoutTestSuite) AfterTest(_, _ string) {
	s.env.AssertExpectations(s.T())
}

func TestTimeoutTestSuite(t *testing.T) {
	suite.Run(t, new(TimeoutTestSuite))
}

func (s *TimeoutTestSuite) Test_Timeouts_2() {
	// Make activity run longer than timeouts
	s.env.OnActivity(NoopActivity2, mock.Anything).Return(nil).After(30 * 24 * time.Hour).Once()

        // example 1: timeout set in test
	s.env.SetStartWorkflowOptions(client.StartWorkflowOptions{WorkflowExecutionTimeout: 1 * time.Hour})
	s.env.ExecuteWorkflow(NoOp)
	s.True(s.env.IsWorkflowCompleted())
	s.Error(s.env.GetWorkflowError()) // expect timeout error here but not the case
}

func (s *TimeoutTestSuite) Test_Timeouts_3() {
	// Make child workflows run longer than timeouts
	s.env.OnWorkflow(NoopChild, mock.Anything).Return(nil).After(30 * 24 * time.Hour).Once()

	s.env.ExecuteWorkflow(NoOp2)
	s.True(s.env.IsWorkflowCompleted())
	s.Error(s.env.GetWorkflowError()) // expect timeout error here but not the case
}

```

Workflow and activity:

```auto
func NoOp(ctx workflow.Context) error {
	wfOpts := workflow.GetChildWorkflowOptions(ctx)
	options := workflow.ActivityOptions{
		StartToCloseTimeout: wfOpts.WorkflowExecutionTimeout,
	}
	ctx = workflow.WithActivityOptions(ctx, options)
	if err := workflow.ExecuteActivity(ctx, NoopActivity2).Get(ctx, nil); err != nil {
		return err
	}
	return nil
}

func NoopActivity2(ctx context.Context) error {
	logger := activity.GetLogger(ctx)

	logger.Info("HELLO!")

	logger.Info("NoopActivity completed!")
	return nil
}

func NoOp2(ctx workflow.Context) error {
        // example 2: timeout set in workflow
	workflowOptions := workflow.ChildWorkflowOptions{
		WorkflowExecutionTimeout: 2 * time.Second,
	}
	ctx = workflow.WithChildOptions(ctx, workflowOptions)
	if err := workflow.ExecuteChildWorkflow(ctx, NoopChild).Get(ctx, nil); err != nil {
		return err
	}
	return nil
}

func NoopChild(ctx workflow.Context) error {
	return nil
}

```
