LoginSignup
3
0

More than 5 years have passed since last update.

Azure ServiceFabric - ServiceFabric.Mocksを利用したStatefulServiceの単体テスト

Last updated at Posted at 2017-06-13

環境

Visual Studio 2017
Service Fabric SDK 2.6.210
ServiceFabric.Mocks 2.10

SDKとMockのバージョンが異なると実行時エラーとなる場合があります。
MockはSDKのバージョンと合ったものを利用してください。

テスト対象

Azure Service Fabric - Web Apiを実装してみるで実装したデータ更新処理に対してテストを実装する。

HogeStatefulService.cs
public async Task Update(IEnumerable<User> users)
{
    var myDictionary = await this.StateManager.GetOrAddAsync<IReliableDictionary<int, User>>(_dictionaryName);

    using (ITransaction transaction = this.StateManager.CreateTransaction())
    {
        foreach (User user in users)
        {
            await myDictionary.AddOrUpdateAsync(transaction, user.Id, user, (key, value) => user);
        }
        await transaction.CommitAsync();
    }
}

環境の準備

テスト用コンストラクタの追加

StateManagerのMockを利用できるように下記のコンストラクタをテスト対象のStatefulServiceに実装する。

HogeStatefulService.cs
public HogeStatefulService(StatefulServiceContext context, IReliableStateManagerReplica reliableStateManagerReplica)
            : base(context, reliableStateManagerReplica)
{}

テストで利用するライブラリの準備

テストプロジェクトを作成し、Moqと ServiceFabric.MocksをNugetから取得

Package Manager Consoleで下記を実行

ServiceFabric.Mocks
PM> Install-Package ServiceFabric.Mocks -Version 2.1.0

GUIでNugetから取得する場合、ServiceFabric.Mocksの"s"まで入力しないとなぜか検索に引っかからないので注意(これだけ完全一致???)

テスト実装

ServiceContextFactoryとStateManagerのMockを作成

    StatefulServiceContext context = MockStatefulServiceContextFactory.Default;
    MockReliableStateManager mockStateManager = new MockReliableStateManager();

上記Mockを利用してテスト対象のインスタンスを生成

    HogeStatefulService target = new HogeStatefulService(context, mockStateManager);

初期データを登録(必要な場合)

    IReliableDictionary<int, User> dictionary = await mockStateManager.GetOrAddAsync<IReliableDictionary<int, User>>("MyDictionary");
    IEnumerable<User> setupDataSet = new List<User>
    {
        new User{ Id = 1, FirstName = "太郎", LastName = "山田"},
        new User{ Id = 2, FirstName = "花子", LastName = "山田"}
    };

    using (ITransaction transaction = mockStateManager.CreateTransaction())
    {
        foreach (var setupData in setupDataSet)
        {
            await dictionary.AddAsync(transaction, setupData.Id, setupData);
        }
        await transaction.CommitAsync();
    }

テストの実行

    await target.Update(new List<User> { new User { Id = 1, FirstName = "次郎", LastName = "山本" } });

Assert

    using (ITransaction transaction = mockStateManager.CreateTransaction())
    {
        User result = (await dictionary.TryGetValueAsync(transaction, 1)).Value;

        Assert.AreEqual(1, result.Id);
        Assert.AreEqual("次郎", result.FirstName);
        Assert.AreEqual("山本", result.LastName);
    }

テストコード全体

[TestMethod]
public async Task UpdateTest()
{
    // setup
    StatefulServiceContext context = MockStatefulServiceContextFactory.Default;
    MockReliableStateManager mockStateManager = new MockReliableStateManager();

    HogeStatefulService target = new HogeStatefulService(context, mockStateManager);
    IReliableDictionary<int, User> dictionary = await mockStateManager.GetOrAddAsync<IReliableDictionary<int, User>>("MyDictionary");
    IEnumerable<User> setupDataSet = new List<User>
    {
        new User{ Id = 1, FirstName = "太郎", LastName = "山田"},
        new User{ Id = 2, FirstName = "花子", LastName = "山田"}
    };

    using (ITransaction transaction = mockStateManager.CreateTransaction())
    {
        foreach (var setupData in setupDataSet)
        {
            await dictionary.AddAsync(transaction, setupData.Id, setupData);
        }
        await transaction.CommitAsync();
    }

    // Act
    await target.Update(new List<User> { new User { Id = 1, FirstName = "次郎", LastName = "山本" } });

    // Assert
    using (ITransaction transaction = mockStateManager.CreateTransaction())
    {
        User result = (await dictionary.TryGetValueAsync(transaction, 1)).Value;

        Assert.AreEqual(1, result.Id);
        Assert.AreEqual("次郎", result.FirstName);
        Assert.AreEqual("山本", result.LastName);
    }
}

まとめ

ServiceFabric.MocksのStateManagerのMockを利用することで、StateManagerのTransaction管理やデータの永続化を利用している部分のテストが可能となる。

参考:GitHub - ServiceFabric.Mocks

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0