首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >测试需要转发到

测试需要转发到
EN

Stack Overflow用户
提问于 2017-10-10 16:18:49
回答 1查看 230关注 0票数 0

我已经创建了一个希望被转发到

代码语言:javascript
运行
复制
using Microsoft.Bot.Builder.Dialogs;
using pc.apm.bot.Services;
using System;
using System.Diagnostics;
using System.Threading.Tasks;

namespace pc.apm.bot.Dialogs
{
    [Serializable]
    public class NewUserDialog : IDialog<string>
    {
        IApmService _apmService;
        LangaugeCodes _langaugeCode;

        public NewUserDialog(IApmService apmService, LangaugeCodes langaugeCode)
        {
            _apmService = apmService;
            _langaugeCode = langaugeCode;
        }

        public async Task StartAsync(IDialogContext context)
        {
            if (new TraceSwitch("apmDiagnostics", "").Level == TraceLevel.Info)
                await context.PostAsync($"Current Dialog: {this.GetType().Name}");

            context.Wait<string>(MessageReceivedAsync);
        }

        private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<string> result)
        {
            var userEmail = await result;

            await context.PostAsync(StringResourceService.GetStringResource(StringKeys.NewUserStarted_Key, _langaugeCode));

            var apmId = await _apmService.CreateUserAsync(userEmail.ToLower());

            var UserProvisionedAlfabet_Text = StringResourceService.GetStringResource(StringKeys.UserProvisionedAlfabet_Key, _langaugeCode);
            await context.PostAsync(String.Format(UserProvisionedAlfabet_Text, userEmail));

            context.Done(apmId);
        }
    }
}

现在它的工作方式是在前面的对话框上,我有一些逻辑决定需要为一个新用户提供服务,如果是这样的话,它就会将用户的电子邮件转发给NewUserDialog。

代码语言:javascript
运行
复制
await context.Forward(
    child: new NewUserDialog(), 
    resume: (c, r) => AddProfile(context, result), 
    item: user.Email,
    token: CancellationToken.None);

因此,所有的工作都很好,而且很好,我遇到的问题是单元测试代码;我正在尝试遵循bot构建器测试项目中列出的内容

https://github.com/Microsoft/BotBuilder/tree/master/CSharp/Tests/Microsoft.Bot.Sample.Tests

现在我的测试开始了,就在我的NewUserDialog试图等待电子邮件地址失败和异常被抛出的时候

pc.apm.bot.tests.Test_New_User_Dialog.Create_New_User抛出异常: Microsoft.Bot.Builder.Internals.Fibers.InvalidTypeException:无效类型:预期的System.String,有活动

因此,我发现这是一个类型问题;但是我不知道如何通过测试代码将电子邮件地址传递给对话框。

这是我的测试代码

代码语言:javascript
运行
复制
using Autofac;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Builder.Dialogs.Internals;
using Microsoft.Bot.Builder.Tests;
using Microsoft.Bot.Connector;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using pc.apm.bot.Dialogs;
using pc.apm.bot.Services;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace pc.apm.bot.tests
{
    [TestClass]
    public class Test_New_User_Dialog : DialogTestBase
    {
        [TestMethod]
        public async Task Test_method() => Assert.IsTrue(await Task.FromResult(true));

        [TestMethod]
        public async Task Create_New_User()
        {
            var mockApmService = new Mock<IApmService>(MockBehavior.Strict);
            mockApmService
                .Setup(m => m.CreateUserAsync(It.IsAny<string>()))
                .Returns<string>(x => Task.FromResult("123-123"));

            var NewUserDialog = new NewUserDialog(mockApmService.Object, LangaugeCodes.en_US);

            var toBot = DialogTestBase.MakeTestMessage();
            toBot.From.Id = Guid.NewGuid().ToString();

            Func<IDialog<string>> MakeRoot = () => NewUserDialog;

            using (new FiberTestBase.ResolveMoqAssembly(NewUserDialog))
            using (var container = Build(Options.MockConnectorFactory | Options.ScopedQueue, NewUserDialog))
            {
                using (var scope = DialogModule.BeginLifetimeScope(container, toBot))
                {
                    DialogModule_MakeRoot.Register(scope, MakeRoot);
                    await Conversation.SendAsync(scope, toBot);

                    var firstResponse = scope.Resolve<Queue<IMessageActivity>>().Dequeue();
                    Assert.IsTrue(firstResponse.Text.Equals("Looks as if you are a new user, let's get you started!"));

                    var secondResponse = scope.Resolve<Queue<IMessageActivity>>().Dequeue();
                    Assert.IsTrue(secondResponse.Text.Equals("A user for pawel.chooch@fake.com has been provisioned in System"));
                }

            }
        }
    }
}

因此,简单地说,我的问题是,如何通过从父对话框转发参数来测试接收参数的对话框?

EN

Stack Overflow用户

回答已采纳

发布于 2017-10-13 09:49:57

好吧,经过大量的努力,我终于得到了它,

代码语言:javascript
运行
复制
using Autofac;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Builder.Dialogs.Internals;
using Microsoft.Bot.Builder.Tests;
using Microsoft.Bot.Connector;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using pc.apm.bot.Dialogs;
using pc.apm.bot.Services;
using pc.apm.bot.tests.Interfaces;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace pc.apm.bot.tests
{
    [TestClass]
    public class Test_New_User_Dialog : DialogTestBase
    {
        [TestMethod]
        public async Task Test_method() => Assert.IsTrue(await Task.FromResult(true));

        [TestMethod]
        public async Task Create_New_user_Dialog()
        {
            var mockRootDialog = new Mock<IMessageRecievedDialog<IMessageActivity>>(MockBehavior.Loose);
            var mockApmService = new Mock<IApmService>(MockBehavior.Strict);

            mockApmService.Setup(m => m.CreateUserAsync(It.IsAny<string>()))
                          .Returns<string>(x => Task.FromResult("123-123"));

            var NewUserDialog = new NewUserDialog(mockApmService.Object, LangaugeCodes.en_US);
            var userEmail = "pawel.chooch@fake.com";

            mockRootDialog.Setup(d => d.StartAsync(It.IsAny<IDialogContext>()))
                          .Returns<IDialogContext>(
                                context =>
                                {
                                    context.Wait(mockRootDialog.Object.MessageRecievedAsync);
                                    return Task.CompletedTask;
                                });

            mockRootDialog.Setup(d => d.MessageRecievedAsync(It.IsAny<IDialogContext>(), It.IsAny<IAwaitable<IMessageActivity>>()))
                          .Returns<IDialogContext, IAwaitable<IMessageActivity>>(async (context, message) =>
                          {
                              var email = await message;
                              await context.Forward(
                                  child: NewUserDialog,
                                  resume: async (c, r) =>
                                  {
                                      Assert.AreEqual("123-123", await r);
                                      c.Done<object>(null);
                                  },
                                  item: email.Text,
                                  token: CancellationToken.None);
                          });

            var toBot = DialogTestBase.MakeTestMessage();

            using (new FiberTestBase.ResolveMoqAssembly(mockRootDialog.Object, NewUserDialog))
            using (var container = Build(Options.MockConnectorFactory | Options.ScopedQueue, mockRootDialog.Object, NewUserDialog))
            using (var scope = DialogModule.BeginLifetimeScope(container, toBot))
            {
                DialogModule_MakeRoot.Register(scope, () => mockRootDialog.Object);

                var task = scope.Resolve<IPostToBot>();
                toBot.Text = userEmail;
                await task.PostAsync(toBot, CancellationToken.None);

                var firstResponse = scope.Resolve<Queue<IMessageActivity>>().Dequeue();
                Assert.IsTrue(firstResponse.Text.Equals("Looks as if you are a new user, let's get you started!"));

                var secondResponse = scope.Resolve<Queue<IMessageActivity>>().Dequeue();
                Assert.IsTrue(secondResponse.Text.Equals($"A user for {userEmail} has been provisioned in ALFABET"));
            }
        }
    }
}

现在撇开apm服务不说,我创建了一个接口IMessageRecievedDialog。

代码语言:javascript
运行
复制
using Microsoft.Bot.Builder.Dialogs;
using System.Threading.Tasks;

namespace pc.apm.bot.tests.Interfaces
{
    public  interface IMessageRecievedDialog<T> : IDialog<T>
    {
        Task MessageRecievedAsync(IDialogContext context, IAwaitable<T> result);
    }
}

实际上,这在Microsoft.Bot.Builder.Tests名称空间中并不是必需的,因为有一个接口"IDialogFrames“,这是完全相同的事情。我从DialogTask_Forward测试中再次从Microsoft.bot.builder.tests中获得了解决方案的灵感。

代码语言:javascript
运行
复制
[TestMethod]
public async Task DialogTask_Forward()
{
    var dialogOne = new Mock<IDialogFrames<string>>(MockBehavior.Loose);
    var dialogTwo = new Mock<IDialogFrames<string>>(MockBehavior.Loose);
    const string testMessage = "foo";

    dialogOne
        .Setup(d => d.StartAsync(It.IsAny<IDialogContext>()))
        .Returns<IDialogContext>(async context => { context.Wait(dialogOne.Object.ItemReceived); });

    dialogOne
        .Setup(d => d.ItemReceived(It.IsAny<IDialogContext>(), It.IsAny<IAwaitable<IMessageActivity>>()))
        .Returns<IDialogContext, IAwaitable<IMessageActivity>>(async (context, message) =>
        {
            var msg = await message;
            await context.Forward(dialogTwo.Object, dialogOne.Object.ItemReceived<string>, msg, CancellationToken.None);
        });

    dialogOne
        .Setup(d => d.ItemReceived(It.IsAny<IDialogContext>(), It.IsAny<IAwaitable<string>>()))
        .Returns<IDialogContext, IAwaitable<string>>(async (context, message) =>
        {
            var msg = await message;
            Assert.AreEqual(testMessage, msg);
            context.Wait(dialogOne.Object.ItemReceived);
        });


    dialogTwo
        .Setup(d => d.StartAsync(It.IsAny<IDialogContext>()))
        .Returns<IDialogContext>(async context => { context.Wait(dialogTwo.Object.ItemReceived); });

    dialogTwo
        .Setup(d => d.ItemReceived(It.IsAny<IDialogContext>(), It.IsAny<IAwaitable<IMessageActivity>>()))
        .Returns<IDialogContext, IAwaitable<IMessageActivity>>(async (context, message) =>
        {
            var msg = await message;
            context.Done(msg.Text);
        });

    Func<IDialog<object>> MakeRoot = () => dialogOne.Object;
    var toBot = MakeTestMessage();

    using (new FiberTestBase.ResolveMoqAssembly(dialogOne.Object, dialogTwo.Object))
    using (var container = Build(Options.None, dialogOne.Object, dialogTwo.Object))
    {
        using (var scope = DialogModule.BeginLifetimeScope(container, toBot))
        {
            DialogModule_MakeRoot.Register(scope, MakeRoot);
            var task = scope.Resolve<IPostToBot>();
            toBot.Text = testMessage;
            await task.PostAsync(toBot, CancellationToken.None);

            dialogOne.Verify(d => d.StartAsync(It.IsAny<IDialogContext>()), Times.Once);
            dialogOne.Verify(d => d.ItemReceived(It.IsAny<IDialogContext>(), It.IsAny<IAwaitable<IMessageActivity>>()), Times.Once);
            dialogOne.Verify(d => d.ItemReceived(It.IsAny<IDialogContext>(), It.IsAny<IAwaitable<string>>()), Times.Once);

            dialogTwo.Verify(d => d.StartAsync(It.IsAny<IDialogContext>()), Times.Once);
            dialogTwo.Verify(d => d.ItemReceived(It.IsAny<IDialogContext>(), It.IsAny<IAwaitable<IMessageActivity>>()), Times.Once);
        }
    }
}

下面的链接确实帮助了https://channel9.msdn.com/Series/DevOps-for-the-Bot-Framework/Testing-the-Bot-Framework?term=bot

我仍然不太熟悉僵尸框架的特定代码,无法真正提供解释,因此我只是理所当然地认为它是理所当然的。不管怎样,我希望我的腿能帮到别人。干杯。

票数 0
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46671429

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档