かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

async awaitを使ったテストの単体テスト

Windows ストア アプリではasync awaitを使った非同期なメソッドを結構作ることになると思います。そんなメソッドの単体テストのやりかたの紹介です。
今回のテスト対象は、非同期にする意味が全くないですが足し算を行う以下のクラスです。

using System.Threading.Tasks;

namespace App7
{
    public class Calc
    {
        public async Task<int> Add(int x, int y)
        {
            await Task.Delay(1000);
            return x + y;
        }
    }
}

同じソリューションに単体テストライブラリのプロジェクトを作って、そこにApp7プロジェクトを参照設定してCalcクラスを使えるようにします。Express版には単体テストを作成するテンプレートが入ってないので、自分でせっせと以下のようなコードを書きます。

using App7;
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
using System.Threading.Tasks;

namespace UnitTestLibrary1
{
    [TestClass]
    public class CalcTest
    {
        [TestMethod]
        public async Task AddTest()
        {
            var calc = new Calc();
            var answer = await calc.Add(10, 20);
            Assert.AreEqual(30, answer);
        }
    }
}

ポイントはTestMethodアトリビュートをつけているメソッドもasync修飾子をつけるようにしてTaskを戻り値にすることです。
あとは、普通にテストメソッド内でawaitして結果を受け取ってAssertしてやりましょう。

テストプロジェクトを選択した状態でメニューの[テスト]→[実行]→[すべてのテスト]をやるとビルドが実行されテストが実行されます。そしてテストエクスプローラに以下のように結果が表示されます。

いやいや、非同期メソッド素通りしてるだけじゃないの?と最初は思ったんですが、ちゃんとAssert変えてやるとテスト失敗もするしちゃんと実行できてるみたいです。

using App7;
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
using System.Threading.Tasks;

namespace UnitTestLibrary1
{
    [TestClass]
    public class CalcTest
    {
        [TestMethod]
        public async Task AddTest()
        {
            var calc = new Calc();
            var answer = await calc.Add(10, 20);
            // わざと失敗してみる
            Assert.AreEqual(999999, answer);
        }
    }
}

うん、いいね!