During this exercise, you will
- Run a unit test provided for the
TranslateTerm
Activity - Develop and run your own unit test for the
TranslateTerm
Activity - Write assertions for a Workflow test
- Uncover, diagnose, and fix a bug in the Workflow Definition
- Observe the time-skipping feature in the Workflow test environment
Make your changes to the code in the practice
subdirectory (look for
TODO
comments that will guide you to where you should make changes to
the code). If you need a hint or want to verify your changes, look at
the complete version in the solution
subdirectory.
We have provided a unit test for the TranslateTerm
Activity
to get you started. This test verifies that the Activity correctly
translates the term "Hello" to German. Take a moment to study the
test, which you'll find in the activity_test.go
file. Since the
test runs the Activity, which in turn calls the microservice to do
the translation, you'll begin by starting that.
- Open a new terminal and run
go run microservice/translation-service.go
- Run the
go test
command to execute the provided test
Now it's time to develop and run your own unit test, this time verifying that the Activity correctly supports the translation of a different word in a different language.
- Edit the
activity_test.go
file - Copy the
TestSuccessfulTranslateActivityHelloGerman
function, renaming the new function asTestSuccessfulTranslateActivityGoodbyeLatvian
- Change the term for the input from
Hello
toGoodbye
- Change the language code for the input from
de
(German) tolv
(Latvian) - Assert that translation returned by the Activity is
Ardievu
In addition to verifying that your code behaves correctly when used as you intended, it is sometimes also helpful to verify its behavior with unexpected input. The example below does this, testing that the Activity returns the appropriate error when called with an invalid language code.
func TestFailedTranslateActivityBadLanguageCode(t *testing.T) {
testSuite := testsuite.WorkflowTestSuite{}
env := testSuite.NewTestActivityEnvironment()
env.RegisterActivity(TranslateTerm)
input := TranslationActivityInput{
Term: "Hello",
LanguageCode: "xq",
}
_, err := env.ExecuteActivity(TranslateTerm, input)
// Assert that execution returned an error
assert.Error(t, err)
// Assert that this is a Temporal Application Error
var applicationErr *temporal.ApplicationError
assert.True(t, errors.As(err, &applicationErr))
// Assert that the error has the expected message, which identifies
// the invalid language code as the cause
assert.Equal(t, "HTTP Error 400: Unknown language code 'xq'\n", applicationErr.Message())
}
Take a moment to study this code, and then continue with the following steps:
- Edit the
activity_test.go
file - Uncomment the imports on lines 4 and 8
- Copy the entire
TestFailedTranslateActivityBadLanguageCode
function provided above and paste it at the bottom of theactivity_test.go
file - Save the changes
- Run
go test
again to run this new test, in addition to the others
- Edit the
workflow_test.go
file - Uncomment the import on line 6
- Remove
IGNORE
from the function name on line 10 (this was added so the test didn't run in the earlier parts of this exercise, since the function name must begin withTest
to be recognized as a test) - Add assertions for the following conditions
- The Workflow Execution has completed
- The
HelloMessage
field in the result isBonjour, Pierre
- The
GoodbyeMessage
field in the result isAu revoir, Pierre
- Save your changes
- Run
go test
. This will fail, due to a bug in the Workflow Definition. - Find and fix the bug in the Workflow Definition
- Run the
go test
command again to verify that you fixed the bug
There are two things to note about this test.
First, the test completes in under a second, even though the Workflow
Definition contains a workflow.Sleep
call that adds a 15-second delay
to the Workflow Execution. This is because of the time-skipping feature
provided by the test environment.
Second, calls to RegisterActivity
near the top of the test indicate
that the Activity Definitions are executed as part of this Workflow
test. As you learned, you can test your Workflow Definition in isolation
from the Activity implementations by using mocks. The optional exercise
that follows provides an opportunity to try this for yourself.
If you have time and would like an additional challenge, continue with the following steps.
- Make a copy of the existing Workflow Test by running
cp workflow_test.go workflow_mock_test.go
- Edit the
workflow_mock_test.go
file - Add an import for
"github.com/stretchr/testify/mock"
- Rename the test function to
TestSuccessfulTranslationWithMocks
- Delete the line used to register the Activity. This is unnecessary in a Workflow test that uses mock objects for the Activity, since the actual Activity Definition is never executed.
- Make the following changes between where the struct representing
workflow input is defined and where
env.ExecuteWorkflow
is called- Create and populate an instance of the
TranslationActivityInput
struct to represent input passed to the Activity when translating the greeting - Create and populate an instance of the
TranslationActivityOutput
struct to represent output returned by the Activity when translating the greeting - Create a mock that represents the
TranslateTerm
Activity, which will return the output struct you created when called with the input struct you created - Repeat the above three steps, this time creating structs and a mock for the goodbye message
- Create and populate an instance of the
- Save your changes
- Run
go test
to run the tests