How to write unit tests for a Bot Framework v4 Dialog that requires the user to authenticate?

Viewed 841

I'm writing Unit Tests (C#) for Dialogs created with version 4 of the MS Bot Framework. I'm wondering how to unit test a ComponentDialog containing a WaterfallDialog and a OAuthPrompt where one step of the WaterfallDialog requires the user to login using the OAuthprompt?

When I write a Unit Test for such a Dialog using the TestAdapter and TestFlow I get to following exception:

OAuthPrompt.GetUserToken(): not supported by the current adapter

This makes sense because the TestAdapter doesn't have a GetUserTokenAsync method like the BotFrameworkAdapter has (this method it called from OAuthPrompt.GetUserToken).

How can we work around this?

2 Answers

The blunt, honest answer is that this will be extremely difficult to factor properly for unit testing today without making a large investment in working around the limitations of the APIs today.

As you pointed out in this specific case OAuthPrompt has strong ties to the ITurnContext::Adapter property being an instance of BotFrameworkAdapter specifically. This alone is "not good", but coupled with the fact that you can't actually override the APIs on BotFrameworkAdapter that the OAuthPrompt actually needs to call means you're completely stuck unless you use an advanced faking framework that allows for replacing non-virtual members.

Honestly, having looked into this for a bit, I don't think you can work around this right now. I would implore you to raise this an issue in the botbuilder-dotnet repo on GitHub and I will gladly chime in there with a recommendation to the team on how they could go about fixing this.

UPDATE 8/15/2019

Since the original answer, this was refactored to introduce an IUserTokenProvider interface which the OAuthPrompt now checks to see if the current ITurnContext::Adapter supports and, if so, calls through to its implementation. This means you can now mock this interface and implement the proper scenarios for tests.

Related