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

时间:2019-04-23 08:26:14

标签: c# unit-testing botframework moq

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

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
在遇到一些问题后,我尝试在线搜索并遇到以下线程:Auto testing for Microsoft Bot Framework =>但顶部答案中提供的链接都给了我404。.
可悲的是,这个Unit Testing Bot Framework也是如此:(

Test类当前为:

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'"));

        }

    }
}

并且Helper类与我发送的指南相同,除了我将DialogContext更改为ITurnContext。 我不知道如何解决该错误,而且我害怕将自己困在Moq孔中(如果您明白我的意思)。

我希望我描述的一切都足够好,希望有人可以帮助我!在此先感谢(:

编辑: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");
            }
        }
    }

1 个答案:

答案 0 :(得分:0)

根据您的实现,如果您想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>()));