Skip to main content

<mockService>

Description

The <mockService> tag sets up fake responses to integration method calls.

The tag serves the same purpose as <mockData> does for regular HTTP requests. It defines mock responses which will be applied when running automated tests for scripts with $integration calls.

  • When automated tests are running and one of the $integration methods is called from the script, the test runner checks whether there is a corresponding <mockService> tag in the test with the same parameters as the ones passed to the method call.

  • If such a tag exists and its parameters match the expected ones, the test runner uses the response specified in <mockService> as the return value of the method call. No actual requests to external services are made during test runs.

caution
In fact, it is not possible to execute real requests to integration methods from automated tests. If the script contains an $integration call but there is no corresponding <mockService> tag for it with matching parameters, the method return value will be null.

Structure

<mockService> elements should be nested within <test> and have an attribute id="integration". The following child elements are supported:

  • <service> — the integration type. Only the googleSheets is currently supported.

  • <method> — the method called from the script. The following values are allowed:

    • readDataFromCells
    • writeDataToCells
    • writeDataToLine
    • deleteRowOrColumn
    • clearCellData
    • customRequest
  • <parameters> — the list of arguments expected to be passed to the method call, specified as child elements.

For example, the readDataFromCells method accepts four arguments: integrationId, spreadsheetId, sheetName, and cells. The <parameters> element for its mock object may look like this:

<parameters>
<integrationId>4404df16-bfc7-4bc6-9f84-65d02d000217</integrationId>
<spreadsheetId>1gdkEwg2KMeKYJK-yrxgKuk9-uP7ntjtKg5ChDu8906E</spreadsheetId>
<sheetName>Sheet1</sheetName>
<cells>["B4", "D4"]</cells>
</parameters>
  • <response> — the JSON response which will be treated as the method return value when the test is run.

Example

The following example contains a state with a Google Sheets integration. The bot accepts a “todo” command specifying a task and a timestamp. Then it calls writeDataToLine to write down the task time and description to a new line in a spreadsheet.

patterns:
# Here the $nonEmptyGarbage built-in pattern is wrapped into $text,
# which allows extracting the pattern value from $parseTree.
$text = $nonEmptyGarbage || converter = function($parseTree) { return $parseTree.text; }

theme: /
state: AddNote
# The @duckling.time system entity is used for time recognition.
# An alias is provided for the entity for shorter access to its value.
q!: * todo $text @duckling.time::time *
script:
$temp.res = $integration.googleSheets.writeDataToLine(
"a410105c-83a1-45ce-abcf-29c72358c409",
"1gdkEwg2KMeKYJK-yrxgKuk9-uP7ntjtKg5ChDu8906E",
"Sheet1",
[$parseTree._time.value, $parseTree._text]
);
if: $context.response.googleSheets.result === "success"
# The method returns an array of strings like Sheet1!A1:B2 in updatedRanges.
a: I’ve written down a note to “{{$parseTree._text}}” into cells {{$temp.res.updatedRanges[0].split("!")[1]}}.
else:
a: Spreadsheet write operation failed.

A test covering this state may look like this.

<test>
<mockService id="integration">
<service>googleSheets</service>
<method>writeDataToLine</method>
<parameters>
<integrationId>a410105c-83a1-45ce-abcf-29c72358c409</integrationId>
<spreadsheetId>1gdkEwg2KMeKYJK-yrxgKuk9-uP7ntjtKg5ChDu8906E</spreadsheetId>
<sheetName>Sheet1</sheetName>
<values>["2021-11-26T00:00:00", "wash the dishes"]</values>
</parameters>
<response>
{"updatedRanges": ["Sheet1!A1:B1"]}
</response>
</mockService>

<test-case>
<dateTime>2021-11-25 12:00:00</dateTime>
<q>todo wash the dishes tomorrow</q>
<a>I’ve written down a note to “wash the dishes” into cells A1:B1.</a>
</test-case>
</test>
note
  • Since the state involves time recognition via the @duckling.time entity, a <dateTime> fixture is required in the test case so that it works correctly.

    The <response> value doesn’t need to contain all fields returned by the integration: you may include only the ones actually used in the bot script.