単体テストを行っているメソッド呼び出しがあります。そのメソッド呼び出し内で、単体テストの実行中に使用できないデバイスと通信しようとしているため、エラーをスローするメソッドを呼び出します。その内部メソッド呼び出しが呼び出されないようにする方法はありますか?
環境: IDE 内での C# Visual Studio 2010 単体テスト
単体テストを行っているメソッド呼び出しがあります。そのメソッド呼び出し内で、単体テストの実行中に使用できないデバイスと通信しようとしているため、エラーをスローするメソッドを呼び出します。その内部メソッド呼び出しが呼び出されないようにする方法はありますか?
環境: IDE 内での C# Visual Studio 2010 単体テスト
外部依存関係を持つクラスを単体テストしている場合は、注入されたインターフェースを使用して外部依存関係を分離する必要があります。
interface IDevice
{
void Run();
}
interface IDeviceOperator
{
void Operate();
}
class DeviceOperator : IDeviceOperator
{
private readonly IDevice _device;
public DeviceOperator(IDevice device)
{
_device = device;
}
public void Operate()
{
_device.Run();
// test other stuff here
}
}
[TestFixture]
public class DeviceOperatorTests
{
[Test]
public void Test_DeviceOperator_Operate()
{
IDevice device = A.Fake<IDevice>(); // Using FakeItEasy 3rd party mocking framework syntax
DeviceOperator deviceOperator = new DeviceOperator(device);
deviceOperator.Operate();
}
}
単体テストを行うときは、すべての外部依存関係に対してモックまたはスタブを作成する必要があります。これに役立つフレームワークがMoq です(探索したい場合は、たくさんのモック フレームワークがあります)。
これらのモックまたはスタブは、テストに合格するために必要な相互作用とデータを提供する単なるファサードです。
使用できないデバイスについて詳しく教えていただけると、さらにお役に立てる可能性があります。
おそらくもっと良い方法がありますが、メソッドが別の複雑なメソッドを呼び出し、テストしているメソッドの最後にオプションのパラメーターを置くこの状況に1、2回ありました
public void DoSomething(int number, bool skipMethod= false)
{
if(!skipMethod)
MethodThatWillBreak();
{
そのため、通常の実行過程では問題ありませんが、単体テストでは次のことができます
DoSomething(2,true);
しかし実際には、単体テストは 1 つの「単位」しかヒットしないため、コードのリファクタリングを行う必要があることを示唆しています。を呼び出さずにメソッドをテストできる場合、MethodThatWillBreak
そもそもそこで何をしているのか。
Michael Feathers 著のWorking Effectively with Legacy Code book をチェックしてください- まだ単体テストがないコードを扱うための多くの提案があります。
本でカバーされている可能なアプローチ:
クラスから派生するためのサンプル:
public class WithComplexDependency
{
public void DoSomething()
{
// Extract original code into a virtual protected method
// dependency.MethodThatWillBreak();
CallMethodThatWillBreak();
}
virtual protected void CallMethodThatWillBreak()
{
dependency.MethodThatWillBreak();
}
}
テスト コードでは、クラスから派生し、独自の実装を提供します。
public class WithMockComplexDependency : WithComplexDependency
{
// may also need to add constructor to call original one.
override protected void CallMethodThatWillBreak()
{
// do whatever is needed for your test
}
}
...
WithComplexDependency testObject = new WithMockComplexDependency();
testObject.DoSomething(); // now does not call dependency.MethodThatWillBreak()
...
単体テストを正しく行うには、デバイスとの通信をテストするクラスから分離する必要があります。インターフェイスを実装する別のクラスでデバイスへのパーティトークを抽象化し、テスト中のオブジェクトの ctor に通信クラスを注入します。これで、外部からモック実装を注入してエラーを回避できます。mmock 実装は、それに対する呼び出しもログに記録できます。またはテストを緩和する定義済みの方法で応答します。依存性注入と制御の反転を読み取る
おそらく、外部をスキップしたくないでしょう。代わりに、外部デバイスへのアクセスなど、外部の依存関係を分離する必要があります。これを行うには多くの方法があります。Moq や RhinoMock などのサードパーティの分離フレームワークを使用できます。Moles フレームワークを使用できます (VS2010 を使用しているため) - .NET メソッドをデリゲート http://research.microsoft.com/en-us/projects/moles/に置き換えます 。TypeMock などの有料分離フレームワーク。d. または、インターフェイスで使用する手書きの偽の実装と、テストで偽の実装を使用するだけです。
通常、テストしているクラスから外部依存関係を抽出し、単体テストで偽の依存関係と交換します。それらを分離して、興味のある部分をテストします。制御の反転と、多くのモッキング フレームワーク ( Moq、Rhino Mocksなど)の 1 つを調べることをお勧めします。