CheckExceptionは0・パラメータ法を受け入れます。どのように私は他の方法が例外をスローテストするのですか?

StackOverflow https://stackoverflow.com/questions/4613152

質問

私はDUnitので例外をテストするためのベストプラクティス何思ったんだけど。私は、Delphiでのメソッドポインタに精通していないです。それは引数なしで実行することができるようにメソッドポインタにバインド引数のいずれかの可能性があります。現時点では私はいつもこの手で「結合」し、追加の方法を記述します。 SUTは、メソッドを投げるの多くを持っている場合、これは厄介なことになるだろう。

// What i did before i knew abput CheckExcepion
procedure MyTest.MyMethod_BadInput_Throws;
var
    res: Boolean;
begin
    res := false;
    try
        sut.MyMethod('this is bad');
    except
        on e : MyExpectedException do:
            res := true;
    end;
    CheckTrue(res);
end;

// What i do now
procedure MyTest.MyMethodWithBadInput;
begin
    sut.MyMethod('this is bad');
end;

procedure MyTest.MyMethod_BadInput_Throws;
begin
    CheckException(MyMethodWithBadInput, MyExpectedException);
end;

// this would be nice
procedure MyTest.MyMethod_BadInput_Throws;
begin
    CheckException(
        BindArguments(sut.MyMethod, 'this is bad'),  // <-- how to do this
        MyExpectedException);
end;
役に立ちましたか?

解決

あなたが)あなたのあなたのメソッド呼び出しを囲むようにStartExpectingExceptionを使用することができます。

StartExpectingException(MyException);
MyMethod(MyParam);
StopExpectingException();

他のヒント

のDUnitはまだそれをサポートしているかどうかは知りませんが、これはDUnitのがそれをサポートしていない場合、あなたは簡単にソースを自分で変更することができますデルファイ2010年に導入された匿名メソッドのための完璧なユースケースです。

のように、これは匿名メソッドのための絶好の場所です、注意します。

ここで私はそれを行う方法です。私はアレックスCiobanuからこれを "借り" ます:

procedure TestTMyClass.CheckException(aExceptionType: TClassOfException; aCode: TTestCode; const aMessage: String);
var
  WasException: Boolean;
begin
  WasException := False;
  try
    aCode;
  except
    on E: Exception do
    begin
      if E is aExceptionType then
      begin
        WasException := True;
      end;
    end;
  end;
  Check(WasException, aMessage);
end;

次にようなものでそれを呼び出します

CheckException(ETestingException, 
             procedure begin FMyClass.RaiseTestingException end,      
             'The ETestingException exception didn''t get raised.  That is impossible!');
使用するにStartExpectingException()は、あなたがより多く、テストに1例外のケースをしたい場合には最良の方法ではありません。例外と一緒に、私のテスト手順のすべての可能なケースをテストするために、私は、このアルゴリズムを使用します:

uses
  Dialogs;
procedure MyTest.MyMethod_Test;
begin
  // Test for Exceptions
  try
    MyMethod(MyParam1CreatingException1);
    ShowMessage('Error! There should have been exception: Exxx here!');
    Check(false);
  except on E: Exception do Check(E is  ExceptionType1); end; // This exception is OK
  try
    MyMethod(MyParam2CreatingException2);
    ShowMessage('Error! There should have been exception: Exxx here!');
    Check(false);
  except on E: Exception do Check(E is  ExceptionType2); end; // This exception is OK
  // ... test other exceptions ...

  // Test other parameters
  CheckEquals('result1', MyMethod(MyParam1));
  CheckEquals('result2', MyMethod(MyParam2));
  // ... other tests ...
end;

は、私が代わりに提供さShowMessage('Error! There should be exception: Exxx here!'); 方法のCheck(false, 'There should have been an EListError.');を使用する理由は、私の場合(Delphi6)にCheck(boolean, 'Message')は仕事をしないということである - それはチェックが内部try...exceptブロック(理由は分からない)である場合にはメッセージは表示されません。

これはニック・ホッジス答えの作業と改良版、サブクラスのDUnitのTestFramework.TTestCaseあります:

uses
  TestFramework, System.SysUtils;
type
  TTestCode = reference to procedure;

  TTestCasePlus = class(TestFramework.TTestCase)
    procedure CheckException(
      ExceptionType: TClass; Code: TTestCode; const Message: String = '');
  end;

implementation

procedure TTestCasePlus.CheckException(
  ExceptionType: TClass; Code: TTestCode; const Message: String = '');
{ Check whether some code raises a specific exception type.

Adapted from http://stackoverflow.com/a/5615560/797744

Example:

  Self.CheckException(EConvertError,
                      procedure begin UnformatTimestamp('invalidstr') end);

@param ExceptionType: The exception class which we check if it was raised.
@param Code: Code in the form of an anonymous method that should raise the
  exception.
@param Message: Output message on check failure. }
var
  WasRaised: Boolean;
begin
  WasRaised := False;
  try
    Code;
  except
    on E: Exception do
      if E is ExceptionType then
        WasRaised := True;
  end;
  Check(WasRaised, Message);
end;

例外がStart/StopExpectingException()の上に上げられたかどうかをチェックする。この方法に素敵なボーナスを使用すると、デバッグビルドでテストランナーを実行することができ、それが「例外が発生した。ブレーク?続けますか?」とあなたを悩ませて保持しないということです例外が発生するたびに - 。それが処理されたにもかかわらず、

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top