単体テストを行う際、モックオブジェクトを活用するのは一般的ですが、テストクラス自体が依存するインターフェースを実装する「Self Shunt(自己接続)」パターンを活用すると、よりシンプルで管理しやすいテストコードが書けます。
本記事では、Self Shuntパターンの概要とC#での実装方法を解説し、その利点についても紹介します。
目次
Self Shunt(自己接続)パターンとは?
Self Shunt(自己接続)パターンとは、テストクラス自身が依存するインターフェースを実装することで、テスト対象のクラスを検証する手法です。
通常、モックやスタブを使用して依存関係を解決しますが、このパターンを利用すると、テストコードの可読性が向上し、不要なクラスの作成を省略できます。
Self Shuntを使うメリット
Self Shuntパターンを活用することで、以下のメリットが得られます。
- モックオブジェクトの作成が不要:インターフェースの実装をテストクラス自身が担うため、モックやスタブを別途用意する必要がない。
- テストコードがシンプルになる:余計なクラスを作成しなくて済むため、テストコードが短くなり、管理しやすくなる。
- 依存関係が明確になる:テスト対象クラスとその依存関係をひと目で把握できる。
C#でのSelf Shuntパターンの実装
以下の例では、ILogger
インターフェースを TestClass
(テストクラス)自身が実装し、Self Shuntパターンを適用しています。
public interface ILogger
{
void Log(string message);
}
public class Service
{
private readonly ILogger _logger;
public Service(ILogger logger)
{
_logger = logger;
}
public void Execute()
{
_logger.Log("処理を実行しました");
}
}
using NUnit.Framework;
public class ServiceTest : ILogger
{
private string _logMessage = "";
[Test]
public void Service_Execute_LogsMessage()
{
// Self Shunt: テストクラス自身がILoggerを実装
var service = new Service(this);
service.Execute();
Assert.AreEqual("処理を実行しました", _logMessage);
}
public void Log(string message)
{
_logMessage = message; // ログメッセージをキャプチャ
}
}
ILogger
を実装し、Log
メソッドでメッセージをキャプチャ。Service
クラスの依存をテストクラス自身が解決し、不要なモックを省略。
Self Shuntパターンの注意点
Self Shuntパターンには便利な点が多いですが、いくつかの注意点もあります。
- 複雑なインターフェースには向かない:メソッド数が多いと、テストクラスの実装が冗長になる。
- テストクラスの責務が増える:テストロジックと依存の実装が混在するため、コードの分離が難しくなる場合がある。
- 他のテストフレームワークとの併用に注意:Mockライブラリ(Moqなど)との相性を考慮し、適切な選択をする必要がある。
まとめ
- Self Shuntパターンは、テストクラス自身が依存インターフェースを実装する手法。
- モックを作成せずにテストできるため、テストコードをシンプルに保てる。
- C#ではインターフェースを実装し、依存オブジェクトとして渡すことで適用可能。
- ただし、複雑なインターフェースには適さないため、適用範囲を考慮する必要がある。
Self Shuntパターンは、モックオブジェクトを作る手間を省き、テストの可読性を向上させる便利な手法です。
シンプルな依存関係を持つ場合には特に有効ですが、適用範囲には注意が必要です。C#のテストを効率化したい方は、ぜひこのパターンを活用してみてください。