Unit test Actions on Google Dialogflow locally

二次信任 提交于 2019-12-12 14:55:24

问题


I'm trying to unit test a DialogflowApp locally by using the firebase shell environment. (in a cli do firebase experimental:functions:shell and then call my methods)

I have followed this guide by google https://firebase.google.com/docs/functions/local-emulator but they don't use the DialogflowApp where the invoked function tries to bind a request object containing intents and parameters like this ->

exports.myFunction = functions.https.onRequest((request, response) => {
const app = new App({ request, response });

function myMethod(app) {
    let myArgument = app.getArgument(MY_ARGUMENT);
    app.tell('Here we are responding');
}

let actionMap = new Map();
actionMap.set(MYMETHOD_ACTION, myMethod);

app.handleRequest(actionMap);
});

Regardless of what request object I send in the CLI, like this myFunction(require("../test/testdata.json")), the request body object is empty, like this body: {} which means I can't do app.handleRequest() or app.getArgument(). The error message I get is

RESPONSE RECEIVED FROM FUNCTION: 400, Action Error: no matching intent handler for: null

I thought that if I populated testdata.json with the json request data shown in Actions on Google -> console.actions.google.com -> Simulator it would be valid data but no.

My question is, how can i mock my request data so that I can start unit testing my fullfillment methods locally?

EDIT 1:

firebase > myMethod.post("/").form(require("../test/testdata.json"))
Sent request to function.
firebase > info: User function triggered, starting execution
info: Function crashed
info: TypeError: Cannot destructure property `parameters` of 'undefined' or 'null'.

if we look in dialogflow_app.js we can see this code for fetching an argument value

  getArgument (argName) {
    debug('getArgument: argName=%s', argName);
    if (!argName) {
      error('Invalid argument name');
      return null;
    }
    const { parameters } = this.body_.result;
    if (parameters && parameters[argName]) {
      return parameters[argName];
    }
    return this.getArgumentCommon(argName);
  }

this.body_ is always just empty {}, regardless of how and what I send into the method when running locally.

EDIT 3

firebase > myMethod({method: "post",json: true, body:  require("../test/testdata.json")})

Sent request to function. firebase > info: User function triggered, starting execution info: Function crashed info: TypeError: Cannot destructure property parameters of 'undefined' or 'null'.


回答1:


Invoking a Firebase HTTPS function using the shell requires a different form. It takes the parameters that the request module does, so in order to emulate a webhook, it will be something like this:

myfunction({
  method: 'POST',
  json: true,
  body: require("../test/testdata.json")
});

These three parameters are important:

  • You need to specify that this is a POST operation
  • You need to indicate that the body will be JSON. This will send the correct header and won't try to send the body as x-www-form-urlencoded
  • You need to include the body. As an object is ok because you've set the json parameter to true.


来源:https://stackoverflow.com/questions/48791293/unit-test-actions-on-google-dialogflow-locally

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!