如何使用 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>()));
我正在尝试对 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
在我 运行 遇到一些问题后,我尝试在线搜索并遇到了这个线程:
同样适用于这个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>()));