如何使用 bot 框架(Echobot,使用 ITurnContext)进行单元测试设置

How to make a set up for unit testing with the bot framework (Echobot, using ITurnContext)

我正在尝试对 Echobot 进行单元测试(只是为了了解它的工作原理,以便我可以将它用于我的实际机器人),但有一个问题我无法解决。我面临的问题是我正在使用 ITurnContext 并且我遇到的每个示例都在使用 DialogContext(使用 IWaitable 发送消息)。
ITurnContext 是只可读的,所以我无法在其中设置任何内容,除非我在 SetUp class 中进行设置,这不是那么漂亮 - 但它有效,所以我继续看看会发生什么,但我得到了一个错误:

Message: Moq.MockException : 
Expected invocation on the mock at least once, but was never performed: c => c.PostAsync(Mock<Microsoft.Bot.Builder.ITurnContext:00000001>.Object, "You sent 'test'")
No setups configured.
No invocations performed.

首先,我使用了本指南:https://medium.com/@createdincode/simple-unit-testing-in-microsofts-c-bot-framework-with-nunit-and-moq-345b805ecd1b
在我 运行 遇到一些问题后,我尝试在线搜索并遇到了这个线程: => 但是顶部答案中提供的链接都给我一个 404..
同样适用于这个Unit Testing Bot Framework,可悲的是:(

测试 class 目前是这样的:

namespace EchoBot.UnitTest
{
    [TestFixture]
    class EchoTest
    {
        private Mock<IChatHelper> _chat;
        private EchoBotBot _echobot;
        private Mock<ITurnContext> _context;

        [SetUp]
        public void SetUp()
        {
            _chat = new Mock<IChatHelper>();
            _echobot = new EchoBotBot(_chat.Object);

            var activity = new Activity(ActivityTypes.Message);
            activity.Text = "test";

            _context = new Mock<ITurnContext>();

            _context.Setup(c => c.Activity).Returns(activity);
        }

        [Test]
        public async Task echoBackTest()
        {

            await _echobot.OnTurnAsync(_context.Object);

            _chat.Verify(c => c.PostAsync(_context.Object, "You sent 'test'"));

        }

    }
}

而Helperclass和我发的指南一样,只不过我把DialogContext改成了ITurnContext。 我不知道如何修复此错误,我害怕将自己困在最小起订量漏洞中(如果你明白我的意思的话)。

我希望我描述的一切都足够好并且有人可以帮助我!提前致谢 (:

编辑:EchoBot 的代码

public class EchoBotBot : IBot
    {
        private readonly EchoBotAccessors _accessors;
        private readonly ILogger _logger;

        private IChatHelper _chat;

        public EchoBotBot(IChatHelper chat)
        {
            _chat = chat;
        }

        public EchoBotBot(ConversationState conversationState)
        {
            if (conversationState == null)
            {
                throw new System.ArgumentNullException(nameof(conversationState));
            }

        }


        public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
        {

            if (turnContext.Activity.Type == ActivityTypes.Message)
            {

                var responseMessage = $"You sent '{turnContext.Activity.Text}'\n";
                await turnContext.SendActivityAsync(responseMessage);
            }
            else
            {
                await turnContext.SendActivityAsync($"{turnContext.Activity.Type} event detected");
            }
        }
    }

根据你的实现,如果你想 Verify 如果 SendActivityAsync 已经用正确的参数调用,你可以创建这样的东西。

//Arrange
var mock = new Mock<ITurnContext>();
mock.Setup(m => m.Activity).Returns(new Activity(ActivityTypes.Message) {Text = "test"});

var sut = new EchoBotBot(Mock.Of<IChatHelper>());

//Act
await sut.OnTurnAsync(mock.Object);

//Assert
mock.Verify(m => m.SendActivityAsync(
    It.Is<string>(msg => msg == "You sent 'test'\n"), 
    null, //or It.IsAny<string>()
    "acceptingInput", //or It.IsAny<string>()
    It.IsAny<CancellationToken>()));