2

私は現在、単体テストとモックを完全に開始する過程にあり、次の方法に出くわしましたが、次の方法で動作するモック実装を作成できないようです。

function GetInstance(const AIID: TGUID; 
                       out AInstance; 
                     const AArgs: array of const; 
                     const AContextID: TImplContextID = CID_DEFAULT): Boolean;

TImplContextID整数の単なるタイプエイリアスです)

これは私がどこまで得たかです:

function TImplementationProviderMock.GetInstance(
  const AIID: TGUID;
    out AInstance;
  const AArgs: array of const;
  const AContextID: TImplContextID): Boolean;
var
  lCall: TMockMethod;
begin
  lCall := AddCall('GetInstance').WithParams([@AIID, AContextID]);
  Pointer(AInstance) := FindVarData(lCall.OutParams[0]).VPointer;
  Result := lCall.ReturnValue;
end;

しかし、開いている配列パラメータをどのようにモックするのか理解できませんでしたAArgs。何か案は?

outまた、 -parameterを返す簡単な方法があり、-typedパラメーター(基本的にはレコード、つまり値型)に-notationを使用するのが正しい方法ですかAInstance@TGUID

現在のバージョンのPascalMockでこのメソッドをモックすることは可能ですか?


更新2:わかりやすくするために質問テキストを切り詰めました。もともとは、メイソンの回答が言及しているモックメソッドの次の誤った実装が含まれていました。

function TImplementationProviderMock.GetInstance(
  const AIID: TGUID;
    out AInstance;
  const AArgs: array of const;
  const AContextID: TImplContextID): Boolean;
begin
  Result := AddCall('GetInstance')
           .WithParams([@AIID, AContextID])
           .ReturnsOutParams([AInstance])
           .ReturnValue;
end;

これで、コンパイラは.ReturnsOutParams([AInstance])「変数型配列コンストラクタの引数型が正しくありません」と文句を言いました。

4

2 に答える 2

0

TVarRecの配列として内部的に実装されているconstReturnsOutParamsの配列を期待しているようです。TVarRecは、バリアントのようなものですが異なるレコードであり、コンパイラがそれを埋めるために定義された型が必要です。型指定されていないパラメータは入りません。

この種のことは、おそらくDelphi 2010の拡張RTTIで実行できますが、TVarRecでは実行できません。

于 2010-05-20T15:28:56.770 に答える
0

テストの実装者がモックが内部でどのように実装されているかを知っている必要があるため、OO-POVからは完全に理想的ではない、やや手の込んだソリューションを思いつきましたが、仮定ができないため、それでもある程度許容できると思いますとにかくオープン配列引数の期待値を指定する他の方法について作成しました(少なくともコンパイルされるものはありません)。

だから、これは私のモックされたメソッドの実装が今どのように見えるかです:

function TImplementationProviderMock.GetInstance(
  const AIID: TGUID;
    out AInstance;
  const AArgs: array of const;
  const AContextID: TImplContextID): Boolean;
var
  lCall: TMockMethod;
  lArgs: TOpenArray;
begin
  lArgs := ConcatArrays([ArgsToArray([@AIID]), ArgsToArray(AArgs), ArgsToArray([AContextID])]);
  lCall := AddCall('GetInstance').WithParams(lArgs);
  Pointer(AInstance) := FindVarData(lCall.OutParams[0]).VPointer;
  Result := lCall.ReturnValue;
end;

ご覧のとおり、私のソリューションの核心は、-メソッドに渡すことができる独自のarray of TVarRec(別名)を構築することでした。明示的な引数と開いている配列の引数を1つの新しい配列にマージできるユーティリティルーチンをいくつか作成しました。TOpenArrayWithParams

これがの実装ですConcatArrays

type TOpenArray = array of TVarRec;

function ConcatArrays(const AArrays: array of TOpenArray): TOpenArray;
var
  lLength: Integer;
  lArray: TOpenArray;
  lIdx: Integer;
  lElem: TVarRec;
begin
  lLength := 0;
  for lArray in AArrays do
    Inc(lLength, Length(lArray));
  SetLength(Result, lLength);
  lIdx := -1;
  for lArray in AArrays do
    for lElem in lArray do
      begin
        Inc(lIdx);
        Result[lIdx] := lElem;
      end;
end;

Delphiが動的配列とオープン配列を内部で処理する方法をより深く理解している人が、これらのルーチンを大規模に最適化できるのではないかと強く疑っています。

とにかく、このソリューションがテストサイトに配置されているので、モックメソッドにオープンアレイパラメータさえあるという事実を無視する必要があります。私は単に期待をそのように指定します:

FMock.Expects('GetInstance').WithParams([@IMyIntf, 1, 2, 3, lContextID]).ReturnsOutParam(lDummy).Returns(True);

...ここで、1, 2, 3-bitは実際に予想されるオープン配列引数です。

于 2010-06-11T11:33:27.320 に答える