17

DUnit で単体テストを行っているクラスがあります。いくつかのパブリック メソッドとプライベート メソッドを含む多数のメソッドがあります。

type
  TAuth = class(TDataModule)
  private
    procedure PrivateMethod;
  public
    procedure PublicMethod;
  end;

このクラスの単体テストを作成するには、すべてのメソッドを公開する必要があります。

プライベートメソッドを宣言してテストできるようにする別の方法はありますが、パブリックではありませんか?

4

7 に答える 7

21

それらを公開する必要はありません。保護されます。次に、単体テスト用にクラスをサブタイプ化し、保護されたメソッドを表示できます。例:

type
  TAuth = class(TDataModule)
  protected
    procedure MethodIWantToUnitTest;
  public
    procedure PublicMethod;
  end;

これで、単体テスト用にサブタイプできます。

interface

uses
  TestFramework, Classes, AuthDM;

type
  // Test methods for class TAuthDM
  TestAuthDM = class(TTestCase)
     // stuff
  end;

  TAuthDMTester = class(TAuthDM)
  public
    procedure MethodIWantToUnitTestMadePublic;
  end;

implementation

procedure TAuthDMTester.MethodIWantToUnitTestMadePublic;
begin
  MethodIWantToUnitTest;
end;

ただし、単体テストを行うメソッドがデータ モジュールと非常に密接に関係しているため、非公開にしないと安全ではない場合は、単体にする必要があるコードを分離するために、メソッドのリファクタリングを検討する必要があります。テスト済みで、データ モジュールの内部にアクセスするコード。

于 2009-01-07T22:16:46.420 に答える
9

少しハックですが、これが最もシンプルで明確なアプローチだと思います。次の条件付きコンパイル ディレクティブを使用します。

  {$IfNDef TEST}
  private
  {$EndIf}

単体テスト プロジェクトでは、 で TEST を定義する必要がありますproject → conditional defines。可視性の指定がない場合、それらは公開されます。

注意: プライベート可視性がクラス宣言の最初のものでない場合、以前の定義が取得されます。より安全な方法ですが、より冗長で明確ではありません。

  private
  {$IfDef TEST}
  public
  {$EndIf}

これには、サブクラス化やその他のアプローチよりも多くの利点があります。

  • 余分な複雑さはありません: コードに余分なクラスはありません。
  • 誰も「誤って」サブクラス化してクラスをオーバーライドすることはできません。アーキテクチャを保持します。
  • メソッドが保護されていると言うとき、それがオーバーライドされることをいくらか期待します。あなたのコードを読んでいる人にこれを伝えています。オーバーライドされるべきではない保護されたメソッドは、コード リーダーを混乱させ、私の最初のプログラミング原則を破ります
  • DUnit は独自のユニットにあり、どこにも含まれていません。
  • 乱雑な RTTI には触れません。

それはより明確な解決策であり、選択した回答よりも優れていると思います。

これを使用するときは、メイン プロジェクトの別のディレクトリにビルド オブジェクトを配置するようにテスト プロジェクトも構成します。これにより、TEST ディレクティブを含むバイナリが他のコードと混ざるのを防ぎます。

于 2011-09-13T20:33:55.177 に答える
5

GerardMeszarosによる「 XUnitTestPatterns」の本をお勧めします。

テスト固有のサブクラス

質問:SUTのプライベート状態にアクセスする必要がある場合、コードをテスト可能にするにはどうすればよいですか?

回答:テストに必要な状態または動作を公開するメソッドをSUTのサブクラスに追加します。

...テスト対象システム(SUT)がテスト可能になるように特別に設計されていない場合、テストのある時点で初期化または検証する必要がある状態にテストがアクセスできない場合があります。

この記事では、いつ使用するか、どのリスクを伴うかについても説明しています。

于 2010-03-13T09:50:55.953 に答える
4

一般に、このような状況になると、単一責任の原則に違反していることに気付くことがよくあります。もちろん、私はあなたの特定のケースについて何も知りませんが、おそらく、プライベートメソッドは独自のクラスにある必要があります. TAuth は、プライベート セクションでこの新しいクラスへの参照を保持します。

于 2012-02-07T12:03:11.780 に答える
4

ユニット内に DUnit コードを配置します。その後、好きなものにアクセスできます。

于 2010-03-15T00:29:44.030 に答える
2
{$IFNDEF UNITEST}
private
{$ENDIF}

ほとんどハックではないシンプルなソリューション。私は頻繁にプライベート メソッドをテストする必要がありますが、この手法は複雑さを最小限に抑えます。

于 2014-08-24T17:36:12.807 に答える
2

拡張 RTTI (Delphi 2010 以降)では、RTTI を介してプライベート メソッドを呼び出すことも別のオプションです。この解決策は、プライベート メソッド、フィールド、または内部クラスを持つクラスをテストするにはどうすればよいですか?の最高評価の回答でもあります。

于 2012-11-15T12:34:47.253 に答える