はじめに
扱っているシステムのオリジナルなログサービスにて、出力するログメッセージ内容をUTでテストする必要がありました。
そのときにC#のモックツールであるmoqを利用。
この記事はその際のまとめメモになります。
【注意】
この記事のコードは、実際のコードを記事用に改変し抽出したものでそのままでは動きません。ご了承ください。
テスト対象コード
ログサービス提供側
モック化対象クラスのコードです。
public class LogService
{
// 利用されるメソッド
public void WriteSystemMessageException(SystemMessageException exception)
{
Write(exception.SystemMessage); // モック化したいメソッド
}
// モック化したいメソッド
public void Write(SystemMessage)
{
WriteCore(SystemMessage); // 実際にログを出力するメソッド
}
}
Write
メソッドで直接ログが出力できますが、SystemMessageException
という例外クラス経由でログ出力を行いたいため、WriteSystemMessageException
メソッドが用意されています。
今回は、Write
をモック化したいと考えています。
ログサービス利用側
public class ConsumerOfLogService
{
public LogService logService = new LogService();
public void Index()
{
try
{
raiseError(); // SystemMessageExceptionが発生する処理
}
catch (SystemMessageException sme)
{
logService.WriteSystemMessageException(sme); // ログサービスでログを出力
}
}
}
テスト対象のクラスとメソッドです。
SystemMessageException
例外クラスにログメッセージが含まれており、このログメッセージをテストコード内で取得したいと考えています。
また、利用側のコードでは、LogService
クラスのWriteSystemMessageException
メソッドのみが利用されており、Write
メソッドは直接利用されていません。
moqでテストを書く
ログメッセージを取得し検証するテストコードを書いていきます。
[TestClass]
public class ConsumerOfLogServiceTests
{
[TestMethod]
public void LogService_test()
{
var mock_Log = new Mock<LogService>() { CallBase = true }; // ①
string logMessage = null; // ログメッセージを格納する変数
mock_Log
.Setup(c => c.Write(It.IsAny<SystemMessage>()))
.Callback<SystemMessage>(sm => logMessage = sm.Message); // ②
ConsumerOfLogService target = new ConsumerOfLogService{ logService = mock_Log.Object };
target.Index(); // テスト対象メソッドを実行
mock_Log.Verify(c => c.Write(It.IsAny<SystemMessage>()), Times.Once()); // モックが実行されたか確認
Assert.AreEqual("期待するログメッセージ", logMessage); // 受け取ったログメッセージで期待値検証する
}
}
ポイントとして2点あります。
ポイント①: CallBase = true
で本来の実装を実行させる
①にある、{ CallBase = true }
がないと、今回の場合、モック化したWrite
が実行されません。なぜなら、moqのデフォルトではモック化していないWriteSystemMessageException
は何も処理しない動作となるためです。今回は、Write
メソッドがWriteSystemMessageException
メソッドの裏にいます。
そこで、{ CallBase = true }
を記述することで、本来のWriteSystemMessageException
メソッドの実装のコードを実行され、処理がWrite
メソッドまで到達します。
ポイント②: Callback
でモック化したメソッドが受け取る引数を処理する
②のように、MockインスタンスのCallback
メソッドを利用することで、テスト内変数のlogMessage
にWrite
メソッドが受け取った引数を受取り、処理することができます。
まとめ
moqの機能を利用してオリジナルなログサービスのログメッセージをテストすることができました。