During this exercise, you will
- Run a unit test provided for the
translateTermActivity - Develop and run your own unit test for the
translateTermActivity - 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.
You'll need two terminal windows for this exercise.
- In all terminals, change to the
exercises/testing-code/practicedirectory. - In one terminal, run
npm installto install dependencies.
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 src/mocha/activities.test.ts file. Since the
test runs the Activity, which in turn calls the microservice to do
the translation, you'll begin by starting that.
- In one terminal, run
npm run service - In another terminal, run the
npm testcommand 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
src/mocha/activities.test.tsfile - Copy the
successfully translates "Hello" to Germantest, renaming the new test assuccessfully translates "Goodbye" to Latvian - Change the term for the input from
HellotoGoodbye - 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 following example does this, testing that the Activity returns the appropriate error when called with an invalid language code.
it('fails to translate with bad language code', async () => {
const env = new MockActivityEnvironment();
const input = {
term: "Hello",
languageCode: "xq",
};
try {
await env.run(activities.translateTerm, input);
assert.fail('Expected error was not thrown');
} catch (err: any) {
console.log(err.message)
assert(err.message.includes("HTTP Error 400: Unknown language code \"xq\""));
}
});Take a moment to study this code, and then continue with the following steps:
- Edit the
src/mocha/activites.test.tsfile - Copy the entire
"fails to translate with bad language code"function provided above and paste it at the bottom of thesrc/mocha/activities.test.tsfile - Save the changes
- Run
npm testagain to run this new test, in addition to the others
- Edit the
src/mocha/workflows.test.tsfile - Remove the first and last line of the file to uncomment the test.
- Add assertions for the following conditions
- The
helloMessagefield in the result isBonjour, Pierre - The
goodbyeMessagefield in the result isAu revoir, Pierre
- The
- Save your changes
- Run
npm test. This will fail, due to a bug in the Workflow Definition. - Find and fix the bug in the Workflow Definition
- Run the
npm testcommand 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 sleep call that adds a 10-second delay
to the Workflow Execution. This is because of the time-skipping feature
provided by the test environment.
Second, the test defines a Worker that registers your Activities, meaning 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 src/mocha/workflows.test.ts src/mocha/workflows-mocks.test.ts - Edit the
src/mocha/workflows-mocks.test.tsfile - Add an import for
sinonwithimport sinon from 'sinon'; - Add an import for the Translation Activity input and output
import { TranslationActivityInput, TranslationActivityOutput } from '../shared'; - Rename the test function to
it('successfully completes French translation with a mocked call', async () => { - Make the following changes between where the object representing
workflow input is defined and where the Worker is defined:
- Create and populate an instance of the
TranslationActivityInputobject to represent input passed to the Activity when translating the greeting. Name ithelloInput. - Create and populate an instance of the
TranslationActivityOutputobject to represent output returned by the Activity when translating the greeting. Name ithelloOutput. - Repeat the above two steps, this time creating objects for the goodbye message.
Switch the names from
hellotogoodbye. - Use Sinon to create a mock that represents the
TranslateTermActivity, which will return the output object you created when called with the input object you created:const translateTermMock = sinon.stub(); - Add the following two lines to return mock results for the translations:
translateTermMock.withArgs(helloInput).resolves(helloOutput);translateTermMock.withArgs(goodbyeInput).resolves(goodbyeOutput);
- Create and populate an instance of the
- For the Worker, modify the registered Activities so it uses your mock:
activities: { translateTerm: translateTermMock }, - Save your changes
- Run
npm testto run the tests