您如何在单元测试期间模拟LUIS?

时间:2018-12-05 10:22:11

标签: c# .net botframework

  1. 我一直在寻找有关如何使用Moq模拟LUIS或在Microsoft Botframework上的单元测试中没有的方法的快速样本,教程等,但没有找到。网上有一些人使用了2年,并且与Github的链接不可用。我希望有人可以在这里帮助我。机器人的一些细节:
    • 语言:C#4.4
    • 框架:.NET 4.6
    • Botframework SDK:3.x

示例代码:

            public async Task Process(IDialogContext context, LuisResult luisResult)
            {
                string emoji = luisResult.Query;
                if (emoji.Contains(":)") || emoji.Contains(": )"))
                {
                    await context.PostAsync(":)");
                }
            }

1 个答案:

答案 0 :(得分:1)

LuisResult并不是一个接口,因此通常更难使用模拟框架。

您可以创建自己的接口以及可转发所有调用的实现,以便随后可以模拟该接口。

internal interface ILuisResult
{
    string Query { get; }
}

internal class LuisResultAdapter : ILuisResult
{
    private readonly LuisResult _luisResult;

    public LuisResultAdapter(LuisResult luisResult)
    {
        _luisResult = luisResult;
    }

    public string Query => _luisResult.Query;
}

或者,您可以重构Process,以使其不再直接依赖LuisResult,只需将调用包装成一个函数并传递一个lambda进行测试即可。

    public void CallOptions(IDialogContext context, LuisResult luisResult)
    {
        Process(context, () => luisResult.Query).Wait();
        Process(context, () => "testData").Wait();
    }


    public async Task Process(IDialogContext context, Func<string> query)
    {
        string emoji = query();
        if (emoji.Contains(":)") || emoji.Contains(": )"))
        {
            await context.PostAsync(":)");
        }
    }

编辑:根据注释中的请求,这里是一个更详细的测试示例。

[TestFixture]
public class ProcessFixture
{
    private ILuisResult _luisResult;
    private BotHost _tested;
    private IDialogContext _dialogContext;
    private string _posted = null;

    [SetUp]
    public void SetUp()
    {
        _posted = null;
        _luisResult = Rhino.Mocks.MockRepository.GenerateMock<ILuisResult>();
        _dialogContext = Rhino.Mocks.MockRepository.GenerateMock<IDialogContext>();
        _dialogContext
            .Stub(x => x.PostAsync(Arg<string>.Is.Anything))
            .Do((Func<string, Task>) (s =>
            {
                _posted = s;
                return Task.Factory.StartNew(() => { });
            }));
        _tested = new BotHost(); //this is a made up class so I can call a method on it
    }

    [TestCase("", ExpectedResult = null)]
    [TestCase(":)", ExpectedResult = ":)")]
    [TestCase(": )", ExpectedResult = ":)")]
    public string ProcessCleansUpInputs(string input)
    {
        _luisResult.Stub(x => x.Query).Return(input);
        _tested.Process(_dialogContext, _luisResult).Wait();
        return _posted;
    }
}

正在使用的软件包:

"NUnit" version="3.11.0",以便我有一个xunit框架

"NUnit3TestAdapter" version="3.11.2",以便我可以使用Test-> Windows-> Test Explorer来在我的vs ide中运行测试

"RhinoMocks" version="3.6.1",以便我可以从接口创建存根