使用Bot Framework和DirectLine集成测试(2)

· 2 分钟阅读

在这一部分中,我们将进行 DirectLine 授权并从机器人的响应中获取值。

现在我们已经完成了反序列化,是时候从集合和整体中获取信息了,我们将使用这些信息来获取授权、进行 api 调用并断言结果。

以下解释不会涵盖Bot Framework如何工作的所有基本信息,如果您不明白,请去查看官方文档。

使用 WebClient 进行 API 调用

为了方便我们调用api,我创建了一个utils类,用于保存我们将要使用几次的函数,该类包括用于POST的uploadString和用于GET的downloadString

    public class Utils
    {
        /// <summary>
        /// Uploads to an URL and gets result
        /// </summary>
        /// <typeparam name="T">Type of object you are receiving</typeparam>
        /// <param name="bearer">Token</param>
        /// <param name="url">Url</param>
        /// <param name="serializedJson">Serialized JSON to send</param>
        /// <returns></returns>
        public static T uploadString<T>(string bearer, string url, string serializedJson)
        {
            string serializedResult = "";

            /// Webclient
            using (var client = new WebClient())
            {
                /// Add headers
                client.Headers.Add("Content-Type", "application/json");
                client.Headers.Add("Authorization", $"Bearer {bearer}");

                /// Upload string
                serializedResult = client.UploadString(url, serializedJson);
            }

            /// Get result and return it as an object
            return JsonConvert.DeserializeObject<T>(serializedResult);
        }

        /// <summary>
        /// Downloads from URL
        /// </summary>
        /// <typeparam name="T">Type of object you are receiving</typeparam>
        /// <param name="bearer">Token</param>
        /// <param name="url">Url</param>
        /// <returns></returns>
        public static T downloadString<T>(string bearer, string url)
        {
            string serializedResult = "";

            /// Webclient
            using (var client = new WebClient())
            {
                /// Add headers
                client.Headers.Add("Content-Type", "application/json");
                client.Headers.Add("Authorization", $"Bearer {bearer}");

                /// Download string
                serializedResult = client.DownloadString(url);
            }

            /// Get result and return it as an object
            return JsonConvert.DeserializeObject<T>(serializedResult);
        }
    }

DirectLine 授权

如果你阅读官方文档,你可以找到如何做到这一点,而且非常简单,使用我们的函数就更容易了。首先请记住,我们在 foreach 语句中,因为我们正在对每种情况进行身份验证,如果我们超时,这将意味着测试将失败。

/// Arrange with current requested values
string token, newToken, conversationId;
/// Act

/// 1 - Get token using secret from DirectLine in BotFramework panel
token = Utils.uploadString<DirectLineAuth>(data.Secret, data.DirectLineGenerateTokenEndpoint, "").token;

现在我们有了令牌,它将用于对对话端点进行以下所有调用。

创建对话。

为了与机器人对话,我们首先需要创建一个对话,该对话将返回一个包含对话 ID 的新令牌。

/// 2 -Create a new conversation
var createdConversation = Utils.uploadString<DirectLineAuth>(token, data.DirectLineConversationEndpoint, "");

// This returns a new token and a conversationId
newToken = createdConversation.token;
conversationId = createdConversation.conversationId;

此外,我们确实存储了 newTokenconversationId,用户向机器人发送消息都需要两者。

将活动发送到对话

现在,使用 conversationIdconversationEndpoint,我们可以创建最终端点来发送 Activity,即 json 文件中的 request

/// 3 - Send an activity to the conversation with new token and conversationId
string directlineConversationActivitiesEndpoint = data.DirectLineConversationEndpoint + conversationId + "/activities";
Utils.uploadString<DirectLineAuth>(newToken, directlineConversationActivitiesEndpoint, JsonConvert.SerializeObject(entry.Request));

获取最新消息

在消息历史记录中,在我们发送活动后,机器人应该已经做出响应,因此我们必须获取所有带有水印的消息,然后使用该水印过滤最新的消息/活动。

/// 4 - Get all activities, we get a List<activity> and a watermark
var getLastActivity = Utils.downloadString<ActivityResponse>(newToken, directlineConversationActivitiesEndpoint);

/// 5 - Get the latest activity which is the response we should be expecting
var latestResponse = getLastActivity.activities[Int32.Parse(getLastActivity.watermark)];

这就是这部分的全部内容,下一部分将包括我们从 json 中的 assert 获取文本的部分,将其转换为代码,就像在 Javascript 中但在 C# 中使用 eval() 一样,然后使用 Assert.isTrue() 获得最终的测试结果。

请记住,所有代码都存储在我的 github 中的 this 存储库中。