Windows サービスの単体テストを行うにはどうすればよいですか?
-
09-06-2019 - |
質問
。ネットフレームワーク:2.0優先言語:C#
私は TDD (テスト駆動開発) を初めて使用します。
まず第一に、Windows サービスの単体テストを行うことは可能でしょうか?
Windows サービス クラスは、オーバーライド可能なメソッドを持つ ServiceBase から派生します。
- 開始時
- オンストップ
単体テストが適切な順序でメソッドを呼び出す実際のサービスであるかのように、これらのメソッドの呼び出しをトリガーするにはどうすればよいでしょうか?
この時点で、単体テストを行っているでしょうか?それとも統合テストですか?
WCF サービスの質問を見ましたが、WCF サービスを扱ったことがないため、意味がわかりませんでした。
解決
おそらく、Windows サービスの "OnStart" と "OnStop" のオーバーライドがクラス ライブラリ アセンブリのメソッドを呼び出すだけになるようにアプリを設計することをお勧めします。これにより、クラス ライブラリ メソッドに対する単体テストを自動化でき、また、Windows サービスの実装からビジネス ロジックを抽象化した設計になります。
このシナリオでは、Windows サービス コンテキストでの "OnStart" メソッドと "OnStop" メソッド自体のテストは統合テストとなり、自動化するものではありません。
他のヒント
サービスを直接テストするのではなく、サービスが何を行うかをテストすることによって、Windows サービスの単体テストを行いました。
通常、サービス用に 1 つのアセンブリを作成し、サービスの内容に応じて別のアセンブリを作成します。次に、2 番目のアセンブリに対する単体テストを作成します。
このアプローチの良い点は、サービスが非常に薄いことです。基本的に行うことは、適切なタイミングで適切な作業を行うメソッドを呼び出すことだけです。他のアセンブリには、サービスが実行する予定の作業のすべての部分が含まれています。これにより、テストが非常に簡単になり、必要に応じて再利用または変更が簡単になります。
私なら始めます ここ. 。C# でサービスを開始および停止する方法を示します。
開始するサンプルは次のとおりです
public static void StartService(string serviceName, int timeoutMilliseconds)
{
ServiceController service = new ServiceController(serviceName);
try
{
TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);
service.Start();
service.WaitForStatus(ServiceControllerStatus.Running, timeout);
}
catch
{
// ...
}
}
また、主にコンソール アプリを通じてサービスをテストし、サービスが何を行うかをシミュレートしました。そうすることで単体テストが完全に自動化されます。
私は、実際のシステムへのプロキシのような Windows サービス クラス (サービスの開始/停止時に実行するクラス) を使用します。あなたのサービスの背後にあるコードが他のプログラミングとどのように異なるべきなのかわかりません。onStart メソッドと onStop メソッドは、GUI 上のボタンを押すなど、単に発生するイベントです。
したがって、Windows サービス クラスは、Windows フォームに相当する非常に薄いクラスです。これはビジネス ロジック/ドメイン ロジックを呼び出し、それが行うべきことを実行します。あなたがしなければならないのは、onStart と onStop で呼び出しているメソッドが想定どおりに動作していることを確認することだけです。少なくとも私ならそうするでしょう ;-)
多くの回答が指摘しているように、テスト用に設計することは良い戦略です。 OnStart
そして OnStop
メソッドはドメイン オブジェクトに委任することで非常に薄く保たれます。
ただし、何らかの理由でテストでサービス メソッドを実行する必要がある場合は、次のようなコードを使用して、テスト メソッド内からサービス メソッドを呼び出すことができます ( OnStart
この例では):
serviceInstance.GetType().InvokeMember("OnStart", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance, null, serviceInstance, new object[] {new string[] {}});
テストウィンドウサービス自動電源でオフにし、条件をシャットダウンし、ネットワークが切断されたときにテストウィンドウサービス、接続されたテストウィンドウサービスオプション、オートステルト、マニュアルなど
おそらくガイが最良の答えでしょう。
とにかく、本当にしたい場合は、で説明されているように、単体テストでこれら 2 つのメソッドを呼び出すことができます。 MSDN ドキュメント ただし、保護されているため、Reflection を使用する必要があります。