WCFサービスをモックする簡単な方法は?
-
03-07-2019 - |
質問
WCFサービスを使用しているアプリがあります。次に、アプリに単体テストを追加します。
WCFサービスをモックする必要がある場合があります。これは、サービスから目的の動作を取得するのが難しい場合があるためです(たとえば、サービスが特別な例外をスローする)。
wcfクライアントにさらに別のインターフェイスを追加できますが、クライアント呼び出しが既にインターフェイスを使用しているため、これは少しばかげているようです。
WCFサービスをモックする簡単な方法はありますか?別のインターフェイスレイヤーを作成して、その中のすべての単一のWCF呼び出しをリダイレクトするより簡単ですか?
編集:ほとんどの答えは、WCFサービスの使用についてあまり知らないようです。そのため、いくつかの明確化:
ViewModelからWCFサービスを使用するには、次のような接続を管理する必要があります。
ChannelFactory<IMyWcfService> channelFactory = new ChannelFactory<IMyWcfService>("");
IMyWcfService proxy = channelFactory.CreateChannel();
proxy.CallMyStuff();
proxy.Close();
すべてのトランザクションで接続を開いたり閉じたりする必要があるため、ViewModelにプロキシをWCFに渡すことはできません。このため、RhinoMock / NMockを使用しても機能しません。WCFを使用する場合、プロキシをパラメーターとして取得するViewModelが必要になるためです。
解決
なぜ NMock2 のようなものを使用してIMyWcfService
インターフェースを直接モックできないのですか?
新しいインスタンスをその場で作成できるようにする必要がある場合は、ファクトリを使用してクライアントからChannelFactory<IMyWcfService>
を非表示にします。このようにして、実際のプロキシの代わりにモックを作成するクライアントを提供して、ファクトリを置き換えることができます。
他のヒント
RhinoMocksやNMockなどのモックフレームワークを使用してインターフェイスコントラクトをモックアウトできるため、サービスにIMyServiceが実装されている場合は、モックフレームワークを使用してそのインターフェイスのメソッド呼び出しに期待を設定できます。この概念に慣れていない場合は、IMyServiceを実装するが、テスト中に実際のサービスのふりをする代用オブジェクトを作成するだけです。このように、メソッドが呼び出されると、それらはスタンドインオブジェクトで呼び出され、スタンドインに必要なものを返すことができます。
あなたはMoq
フレームワークをモックできます。指定した例に基づいて:
ChannelFactory<IMyWcfService> channelFactory = new ChannelFactory<IMyWcfService>("");
IMyWcfService proxy = channelFactory.CreateChannel();
proxy.CallMyStuff();
proxy.Close();
モックの実装は次のようになります。
Mock<IMyWcfServiceChannel> channelMock = new Mock<IMyWcfServiceChannel>(MockBehavior.Strict);
channelMock
.Setup(c => c.CallMyStuff())
.Returns("");
string myStuff = channelMock.Object.CallMyStuff();
WCF
サービスのプロキシを追加した後、channel
と呼ばれるIMyWcfServiceChannel
インターフェースが利用可能になります。
呼び出しているサービスメソッドの戻り値のタイプに応じて、ほぼすべての出力を設定できます。上記の例では、例としてstring
タイプを使用しました。
上記のソリューションをより効率的に使用するには、次のようにビジネスレイヤーの2つのコンストラクターを作成することをお勧めします。
public class Example1
{
IMyWcfServiceChannel _client;
public Example1()
{
var factory = new ChannelFactory<IMyWcfServiceChannel>("binding");
_client = factory.CreateChannel();
}
public Example1(IMyWcfServiceChannel client)
{
_client = client;
}
public string CallMyStuff()
{
return _client.CallMyStuff();
}
}
したがって、prod
では、パラメータなしのコンストラクタを使用します。 unit
テストでは、パラメーターの完全なコンストラクターを使用し、モックを渡します(channelMock.Object
)。