Unit Test Flow in Botframework V4

In theory unit testing in Botframework V4 should easy enough as it’s based on .net core. But, as with many things, it might not be that obvious. So here is a quick snippet showing a test for a Waterfall flow;

[TestMethod]
public async Task Waterfall()
{
    var convoState = new ConversationState<Dictionary>(new MemoryStorage());

    var adapter = new TestAdapter()
        .Use(convoState);

    //var dialogState = convoState.CreateProperty("dialogState");
    var dialogs = new DialogSet();
    dialogs.Add("textPrompt", new TextPrompt());

    dialogs.Add("test",
        new WaterfallStep[]
        {
            async (dc, args, next) =>
            {
                    await dc.Context.SendActivity("Welcome! We need to ask a few questions to get started.");
                    await dc.Prompt("textPrompt", "What's your name?");
            },
            async (dc, args, next) =>
            {
                dc.ActiveDialog.State["name"] = args["Value"];
                await dc.Context.SendActivity($"Thanks {args["Value"]}!");
                await dc.End();
            }
        }
    );

    await new TestFlow(adapter, async (turnContext) =>
    {
        var state = turnContext.GetConversationState<Dictionary>();
        var dc = dialogs.CreateContext(turnContext, state);
        await dc.Continue();
        if (!turnContext.Responded)
        {
            await dc.Begin("test");
        }
    })
    .Send("Hello")
    .AssertReply("Welcome! We need to ask a few questions to get started.")
    .AssertReply("What's your name?")
    .Send("Paul")
    .AssertReply("Thanks Paul!")
    .StartTest();
}

A couple of points to note, you have to send a message to start the flow, and make sure you call turnContext.GetConversationState rather than using a local version of the state.

Advertisements

How to Test async and await

This is one of those, “please stop forgetting this dummy” posts aimed at myself. When you want to test an asynchronous method implemented via the Task-based Asynchronous Pattern (TAP) don’t forget to change the default test method;

Default:

[TestMethod]

public void TestAsyncCall() { … }

to

[TestMethod]

public async Task TestAsyncCall() { … }