前回は Authbot と Microsoft Graph を呼べるようにしました。今回は変更したものをユニットテストしてみます。
依存サービスのモック
依存サービスはモックを作り、常に意図した動作をするようにすることで、本当にテストしたい部分のユニットテストを行います。AuthBot と GraphService それぞれモック化します。
AuthBot のモック化
コード内で AuthBot の GetAccessToken メソッドを実行して、OAuth 2.0 のアクセストークンを取得していますが、ここをモック化します。ソースコードを見ると GetAccessToken は静的な部分メソッドですので、Microsoft Fakes を使います。Fakes の詳細はこちら。
1. Fake アセンブリを作るため、ユニットテストプロジェクトにも AuthBot を追加して、各種 NuGet パッケージを最新に更新します。
2. AuthBot 参照を右クリックして、Fakes Assembly を追加します。
3. UnitTest1.cs の ShouldReturnCount メソッドを削除して、以下のように書き換えます。
[TestMethod] public async Task ShouldReturnEvents() { // Fakes を使うためにコンテキストを作成 using (ShimsContext.Create()) { // AuthBot の GetAccessToken メソッドを実行した際、dummyToken というトークンが返るよう設定 AuthBot.Fakes.ShimContextExtensions.GetAccessTokenIBotContextString = async (a, e) => { return "dummyToken"; }; // テストしたいダイアログのインスタンス作成 IDialog rootDialog = new RootDialog(); // Bot に送るメッセージを作成 var toBot = DialogTestBase.MakeTestMessage(); toBot.From.Id = Guid.NewGuid().ToString(); toBot.Text = "get appointments"; // メモリ内で実行できる環境を作成 FuncMakeRoot = () => rootDialog; using (new FiberTestBase.ResolveMoqAssembly(rootDialog)) using (var container = Build(Options.MockConnectorFactory | Options.ScopedQueue, rootDialog)) { // メッセージを送信して、結果を受信 IMessageActivity toUser = await GetResponse(container, MakeRoot, toBot); // 結果の検証 Assert.IsTrue(toUser.Text.Equals("You sent hi! which was 3 characters")); } } }
4. RootDialog.cs の 認証チェックのコードあたりにブレークポイントを置きます。
5. 一旦ソリューションをコンパイルして、テストエクスプローラーより ShouldReturnEvents テストをデバッグ実行します。
6. ブレークポイントがヒットしたらステップ実行して、認証済ロジックに遷移することを確認します。
これで AuthBot の依存は解決しました。
GraphService のモック化
AuthBot と違いソースをもっているので、サービスをインターフェース化して、Moq と AutoFac を使います。
Moq の詳細はこちら。
AutoFac の詳細はこちら。
1. GraphService.cs を開き、GraphService からインターフェースを作成します。
2. インターフェース名は IEventService としました。
3. 次に AutoFac のセットアップをします。Global.asax.cs の中身を以下に差し替えます。IEventService を利用する際、GraphService を返します。
using Autofac; using O365Bot.Services; using System.Configuration; using System.Web.Http; namespace O365Bot { public class WebApiApplication : System.Web.HttpApplication { public static IContainer Container; protected void Application_Start() { GlobalConfiguration.Configure(WebApiConfig.Register); AuthBot.Models.AuthSettings.Mode = ConfigurationManager.AppSettings["ActiveDirectory.Mode"]; AuthBot.Models.AuthSettings.EndpointUrl = ConfigurationManager.AppSettings["ActiveDirectory.EndpointUrl"]; AuthBot.Models.AuthSettings.Tenant = ConfigurationManager.AppSettings["ActiveDirectory.Tenant"]; AuthBot.Models.AuthSettings.RedirectUrl = ConfigurationManager.AppSettings["ActiveDirectory.RedirectUrl"]; AuthBot.Models.AuthSettings.ClientId = ConfigurationManager.AppSettings["ActiveDirectory.ClientId"]; AuthBot.Models.AuthSettings.ClientSecret = ConfigurationManager.AppSettings["ActiveDirectory.ClientSecret"]; var builder = new ContainerBuilder(); builder.RegisterType().As (); } } }
4. RootDialog.cs ファイルの認証済ロジック内を以下のコードをに差し替えます。これにより実行時に動的にサービスをの実装を取得できます。
using (var scope = WebApiApplication.Container.BeginLifetimeScope()) { // 認証済の場合のロジック実行 // IEventService の実体を取得する IEventService service = scope.Resolve(); var events = await service.GetEvents(); foreach (var @event in events) { await context.PostAsync($"{@event.Start.DateTime}-{@event.End.DateTime}: {@event.Subject}"); } }
5. ユニットテストプロジェクトに戻って、Microsoft.Graph NuGet パッケージを追加します。
6. UnitTest1.cs を開き、以下 using を追加します。
using Moq; using Microsoft.Graph;
7. ShouldReturnEvents テストメソッド、IDialog rootDialog = new RootDialog(); の前に以下のコードを追加します。これでテスト時にはモックのサービスを利用します。
// サービスのモック var mockEventService = new Mock(); mockEventService.Setup(x => x.GetEvents()).ReturnsAsync(new List () { new Event { Subject = "dummy event", Start = new DateTimeTimeZone() { DateTime = "2017-05-31 12:00", TimeZone = "Standard Tokyo Time" }, End = new DateTimeTimeZone() { DateTime = "2017-05-31 13:00", TimeZone = "Standard Tokyo Time" } } }); // IEventService 解決時にモックが返るよう設定 var builder = new ContainerBuilder(); builder.RegisterInstance(mockEventService.Object).As (); WebApiApplication.Container = builder.Build();
8. 先ほどと同じようにテストをデバッグ実行。指定したダミーのイベントが取得されていることを確認。
テストの改修
全てモック化できたので、最後にテストの検証個所を書き換えてテストしましょう。
1. 結果検証を以下のコードに差し替え。
// 結果の検証 Assert.IsTrue(toUser.Text.Equals("2017-05-31 12:00-2017-05-31 13:00: dummy event"));
2. テストエクスプローラーよりテストの実行。
3. テストが成功することを確認。
まとめ
今回は依存サービスのモック化を実施しました。次回は VSTS 側での CI を設定します。コードはすべてチェックインしておいてください。
This post first appeared on MSDN Blogs | Get The Latest Information, Insights, Announcements, And News From Microsoft Experts And Developers In The MSDN Blogs., please read the originial post: here