Bot Builder v4.5 のユニットテスト : ダイアログクラスのテスト - DateResolverDialog 

[前回](https://qiita.com/kenakamu/items/471a0479d75c57914fb8) は CancelAndHelpDialog のテストを見ていきましたが、今回は DateResolverDialog のテストを見ていきます。

# DateResolverDialog 

このダイアログでは、日付に特化した検証を行います。

では早速テストを見ていきます。テストは 1 つだけです。

# CancelAndHelpDialog テスト

このテストでは様々な日付のパターンでテストを行います。

```csharp:DateResolverDialogTests.cs
[Theory]
[MemberData(nameof(DateResolverDialogTestsDataGenerator.DateResolverCases), MemberType = typeof(DateResolverDialogTestsDataGenerator))]
public async Task DialogFlowTests(TestDataObject testData)
{
    // Arrange
    var testCaseData = testData.GetObject<DateResolverDialogTestCase>();
    var sut = new DateResolverDialog();
    var testClient = new DialogTestClient(Channels.Test, sut, testCaseData.InitialData, new[] { new XUnitDialogTestLogger(Output) });

    // Execute the test case
    Output.WriteLine($"Test Case: {testCaseData.Name}");
    Output.WriteLine($"\r\nDialog Input: {testCaseData.InitialData}");
    for (var i = 0; i < testCaseData.UtterancesAndReplies.GetLength(0); i++)
    {
        var reply = await testClient.SendActivityAsync<IMessageActivity>(testCaseData.UtterancesAndReplies[i, 0]);
        Assert.Equal(testCaseData.UtterancesAndReplies[i, 1], reply?.Text);
    }

    Output.WriteLine($"\r\nDialog result: {testClient.DialogTurnResult.Result}");
    Assert.Equal(testCaseData.ExpectedResult, testClient.DialogTurnResult.Result);
}
```

## テストパターンの作成

今回は [BookingDialog のテスト]() 同様 MemberData 属性を使ってテストを取得しています。

### DateResolverDialogTestsDataGenerator クラス

テストは DateResolverDialogTestsDataGenerator の BuildTestCaseObject メソッドでテスト用のデータを作成しています。

```csharp:DateResolverDialogTestsDataGenerator .cs
private static object[] BuildTestCaseObject(string testCaseName, string input, string[,] utterancesAndReplies, string result)
{
    var testData = new DateResolverDialogTestCase
    {
        Name = testCaseName,
        InitialData = input,
        ExpectedResult = result,
        UtterancesAndReplies = utterancesAndReplies,
    };
    return new object[] { new TestDataObject(testData) };
}
```
また MemberData で指定されている DateResolverCases メソッドにて、複数のテストオブジェクトを作成しています。

```csharp
public static IEnumerable<object[]> DateResolverCases()
        {
            yield return BuildTestCaseObject(
                "tomorrow",
                null,
                new[,]
                {
                    { "hi", "When would you like to travel?" },
                    { "tomorrow", null },
                },
                $"{DateTime.Now.AddDays(1):yyyy-MM-dd}");

//以下省略
```

初めのテストケースは以下のようになっています。

**名前**
"tomorrow"
**初めに渡される日付文字列**
null
**会話**
{ "hi", "When would you like to travel?" },
{ "tomorrow", null },
**会話の結果作成された日付**
$"{DateTime.Now.AddDays(1):yyyy-MM-dd}");

これは LUIS で必要な日付が取得できなかった場合に、ユーザーが "tomorrow" と日付を指定した場合のフローであることが分かります。
同様に他のテストケースも確認してください。

## テストの実行と結果の確認

作成したテストケースデータを使って DialogTestClinet を作成します。

```csharp
// Arrange
var testCaseData = testData.GetObject<DateResolverDialogTestCase>();
var sut = new DateResolverDialog();
var testClient = new DialogTestClient(Channels.Test, sut, testCaseData.InitialData, new[] { new XUnitDialogTestLogger(Output) });
```

次に指定された会話を最後まで実行します。

```csharp
for (var i = 0; i < testCaseData.UtterancesAndReplies.GetLength(0); i++)
{
    var reply = await testClient.SendActivityAsync<IMessageActivity>(testCaseData.UtterancesAndReplies[i, 0]);
    Assert.Equal(testCaseData.UtterancesAndReplies[i, 1], reply?.Text);
}
```
最後に日付を確認します。

```csharp
Output.WriteLine($"\r\nDialog result: {testClient.DialogTurnResult.Result}");
Assert.Equal(testCaseData.ExpectedResult, testClient.DialogTurnResult.Result);
```

テストエクスプローラーで確認すると、それぞれの結果が出ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/d4101237-508a-bbe3-03f0-1beb7f62e0de.png)

# まとめ

DataMember が出てくるのは 2 度目のため少し慣れたと思います。次回はシリーズの最終回で、コントローラーのテストとまとめです。

[次の記事へ](https://qiita.com/kenakamu/items/b9e531778ad9cd4d6dc7)
[目次へ戻る](https://qiita.com/kenakamu/items/6dc043cfc1f199032883)