Google Dialogflow 本地单元测试操作
Unit test Actions on Google Dialogflow locally
我正在尝试使用 firebase shell 环境在本地对 DialogflowApp
进行单元测试。 (在 cli 中执行 firebase experimental:functions:shell 然后调用我的方法)
我已按照 google https://firebase.google.com/docs/functions/local-emulator 的指南进行操作,但他们不使用 DialogflowApp,其中调用的函数试图绑定包含这样的意图和参数的请求对象 ->
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);
});
无论我在 CLI 中发送什么请求对象,像这样 myFunction(require("../test/testdata.json"))
,请求主体对象都是空的,像这样 body: {}
这意味着我不能做 app.handleRequest()
或 app.getArgument()
。我收到的错误消息是
RESPONSE RECEIVED FROM FUNCTION: 400, Action Error: no matching intent
handler for: null
我想如果我用 Google -> console.actions.google.com -> 模拟器上的操作中显示的 json 请求数据填充 testdata.json 它将是有效数据,但是不。
我的问题是,如何模拟我的请求数据,以便我可以在本地开始单元测试我的 fullfillment 方法?
编辑 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'.
如果我们查看 dialogflow_app.js,我们可以看到这段用于获取参数值的代码
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_ 总是空的 {}
,无论我在本地 运行 时如何以及向方法发送什么。
编辑 3
firebase > myMethod({method: "post",json: true, body: require("../test/testdata.json")})
已发送功能请求。
firebase > 信息:触发用户函数,开始执行
信息:功能崩溃
信息:TypeError:无法解构 'undefined' 或 'null'.
的 属性 parameters
使用 shell 调用 Firebase HTTPS 函数需要 different form。它采用请求模块所做的参数,因此为了模拟 webhook,它将是这样的:
myfunction({
method: 'POST',
json: true,
body: require("../test/testdata.json")
});
这三个参数很重要:
- 您需要指定这是一个POST操作
- 您需要指明 body 将是 JSON。这将发送正确的 header 并且不会尝试将 body 作为 x-www-form-urlencoded
发送
- 您需要包含 body。 object 没问题,因为您已将 json 参数设置为 true。
我正在尝试使用 firebase shell 环境在本地对 DialogflowApp
进行单元测试。 (在 cli 中执行 firebase experimental:functions:shell 然后调用我的方法)
我已按照 google https://firebase.google.com/docs/functions/local-emulator 的指南进行操作,但他们不使用 DialogflowApp,其中调用的函数试图绑定包含这样的意图和参数的请求对象 ->
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);
});
无论我在 CLI 中发送什么请求对象,像这样 myFunction(require("../test/testdata.json"))
,请求主体对象都是空的,像这样 body: {}
这意味着我不能做 app.handleRequest()
或 app.getArgument()
。我收到的错误消息是
RESPONSE RECEIVED FROM FUNCTION: 400, Action Error: no matching intent handler for: null
我想如果我用 Google -> console.actions.google.com -> 模拟器上的操作中显示的 json 请求数据填充 testdata.json 它将是有效数据,但是不。
我的问题是,如何模拟我的请求数据,以便我可以在本地开始单元测试我的 fullfillment 方法?
编辑 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'.
如果我们查看 dialogflow_app.js,我们可以看到这段用于获取参数值的代码
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_ 总是空的 {}
,无论我在本地 运行 时如何以及向方法发送什么。
编辑 3
firebase > myMethod({method: "post",json: true, body: require("../test/testdata.json")})
已发送功能请求。 firebase > 信息:触发用户函数,开始执行 信息:功能崩溃 信息:TypeError:无法解构 'undefined' 或 'null'.
的 属性parameters
使用 shell 调用 Firebase HTTPS 函数需要 different form。它采用请求模块所做的参数,因此为了模拟 webhook,它将是这样的:
myfunction({
method: 'POST',
json: true,
body: require("../test/testdata.json")
});
这三个参数很重要:
- 您需要指定这是一个POST操作
- 您需要指明 body 将是 JSON。这将发送正确的 header 并且不会尝试将 body 作为 x-www-form-urlencoded 发送
- 您需要包含 body。 object 没问题,因为您已将 json 参数设置为 true。