2

単体テストを行っているメソッド呼び出しがあります。そのメソッド呼び出し内で、単体テストの実行中に使用できないデバイスと通信しようとしているため、エラーをスローするメソッドを呼び出します。その内部メソッド呼び出しが呼び出されないようにする方法はありますか?

環境: IDE 内での C# Visual Studio 2010 単体テスト

4

7 に答える 7

5

外部依存関係を持つクラスを単体テストしている場合は、注入されたインターフェースを使用して外部依存関係を分離する必要があります。

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();
    }
}
于 2013-05-15T16:11:17.303 に答える
2

単体テストを行うときは、すべての外部依存関係に対してモックまたはスタブを作成する必要があります。これに役立つフレームワークがMoq です(探索したい場合は、たくさんのモック フレームワークがあります)。

これらのモックまたはスタブは、テストに合格するために必要な相互作用とデータを提供する単なるファサードです。

使用できないデバイスについて詳しく教えていただけると、さらにお役に立てる可能性があります。

于 2013-05-15T16:03:06.523 に答える
1

おそらくもっと良い方法がありますが、メソッドが別の複雑なメソッドを呼び出し、テストしているメソッドの最後にオプションのパラメーターを置くこの状況に1、2回ありました

public void DoSomething(int number, bool skipMethod= false)
{
    if(!skipMethod)
        MethodThatWillBreak();
{

そのため、通常の実行過程では問題ありませんが、単体テストでは次のことができます

DoSomething(2,true);

しかし実際には、単体テストは 1 つの「単位」しかヒットしないため、コードのリファクタリングを行う必要があることを示唆しています。を呼び出さずにメソッドをテストできる場合、MethodThatWillBreakそもそもそこで何をしているのか。

于 2013-05-15T16:05:02.080 に答える
1

Michael Feathers 著のWorking Effectively with Legacy Code book をチェックしてください- まだ単体テストがないコードを扱うための多くの提案があります。

本でカバーされている可能なアプローチ:

  • インターフェイスで依存関係を抽出する - 理想的なアプローチ (jamespconnor の回答を参照)
  • フラグを使用して呼び出しをバイパスします(Colm Pruntyの回答を参照)
  • その呼び出しを仮想メソッドに抽出し、単体テストで使用される派生クラスでオーバーライドします
  • デリゲートを渡す (完全なインターフェイス/派生よりも影響が少ない可能性があります)

クラスから派生するためのサンプル:

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()
...
于 2013-05-15T16:49:15.187 に答える
0

単体テストを正しく行うには、デバイスとの通信をテストするクラスから分離する必要があります。インターフェイスを実装する別のクラスでデバイスへのパーティトークを抽象化し、テスト中のオブジェクトの ctor に通信クラスを注入します。これで、外部からモック実装を注入してエラーを回避できます。mmock 実装は、それに対する呼び出しもログに記録できます。またはテストを緩和する定義済みの方法で応答します。依存性注入と制御の反転を読み取る

于 2013-05-15T16:05:51.823 に答える
0

おそらく、外部をスキップしたくないでしょう。代わりに、外部デバイスへのアクセスなど、外部の依存関係を分離する必要があります。これを行うには多くの方法があります。Moq や RhinoMock などのサードパーティの分離フレームワークを使用できます。Moles フレームワークを使用できます (VS2010 を使用しているため) - .NET メソッドをデリゲート http://research.microsoft.com/en-us/projects/moles/に置き換えます 。TypeMock などの有料分離フレームワーク。d. または、インターフェイスで使用する手書きの偽の実装と、テストで偽の実装を使用するだけです。

于 2013-05-16T08:13:41.053 に答える
0

通常、テストしているクラスから外部依存関係を抽出し、単体テストで偽の依存関係と交換します。それらを分離して、興味のある部分をテストします。制御の反転と、多くのモッキング フレームワーク ( MoqRhino Mocksなど)の 1 つを調べることをお勧めします。

于 2013-05-15T16:06:14.193 に答える