3

Spring フレームワークから Nullable 型を使用して Delphi DSharp モックをセットアップする最良の方法は何ですか? さまざまなアプローチを試してみましたが、おそらく本当に初歩的なものが欠けていることはわかっていますが、次のコードを機能させる方法がわかりません。

program DSharkMockNullable;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  DSharp.Testing.Mock,
  Spring,
  System.SysUtils;

type

  {$M+}
  IBaseMock = interface
  ['{B3311345-3C1F-47E3-8235-57B1BA04E957}']
    function GetId:  TNullableInteger;
    procedure SetId(Value: TNullableInteger);
    property Id: TNullableInteger read GetId write SetId;
  end;

  {$M+}
  IMockMe = interface(IBaseMock)
  ['{07F8F233-E8F5-4743-88C5-97A66BB01E29}']
    function GetObjectId:  TNullableInteger;
    procedure SetObjectId(Value: TNullableInteger);
    property ObjectId: TNullableInteger read GetObjectId write SetObjectId;
    function GetObjectName:  TNullableString;
    procedure SetObjectName(Value: TNullableString);
    property ObjectName: TNullableString read GetObjectName write SetObjectName;
  end;

  TMyObject = class
  public
    function ObjectIdAsString(const AObject: IMockMe): string;
  end;


{ TMyObject }

function TMyObject.ObjectIdAsString(const AObject: IMockMe): string;
var
  LId: Integer;
  LObjectId: Integer;
  LObjectName: string;
begin
  LId := AObject.Id;  // ***** FAILS HERE with an "Invalid Typecast" error
  LObjectId := AObject.ObjectId;
  LObjectName := AObject.ObjectName;
  Result := Format('Id: %d', [LId]);
  Result := Format('Object Id: %d', [LObjectId]);
  Result := Format('Object Name: %s', [LObjectName]);
end;

var
  LMock: Mock<IMockMe>;
  LObject: TMyObject;
begin
  try
    LMock.Setup.WillReturn(123).Any.WhenCalling.Id;
    LMock.Setup.WillReturn(456).Any.WhenCalling.ObjectId;
    LMock.Setup.WillReturn('blahblah').Any.WhenCalling.ObjectName;

    LObject := TMyObject.Create;
    Writeln(LObject.ObjectIdAsString(LMock.Instance));
    LObject.Free;

    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

アイデアや提案は素晴らしいでしょうか?Delphi XE5 を使用しています。ありがとう。リック。

4

2 に答える 2

6

正しいコードは次のようになります (型推論は使用しません)。

LMock.Setup.WillReturn<TNullableInteger>(123).Any.WhenCalling.Id;
LMock.Setup.WillReturn<TNullableInteger>(456).Any.WhenCalling.ObjectId;
LMock.Setup.WillReturn<TNullableString>('blahblah').Any.WhenCalling.ObjectName;

リックがすでにここで与えた正しい答えに加えて、なぜそれが当てはまるのかについての説明:

元のコードは、WillReturn に渡される値に対して型推論を使用し、それらをShortInt, SmallInt(コンパイラは適合する最小の符号付き序数型を使用します) および. として推論しますstring。これらは として保存されTValue、メソッドが呼び出されたときに返されます。TValueしかし、RTTIは戻り値の型とメソッドにキャストしようとしますが、失敗するのは、型の暗黙の演算子のオーバーロードを認識せず、方法がないため、aShortIntまたはSmallIntaNullable<Integer>または astringにキャストする方法Nullable<string>がわからないためです。カスタムコンバーターを登録します。TValue.TryCastNullable<>

于 2014-06-02T06:22:11.750 に答える
2

わかりました、「DSharp for Dummies」を読むべきでしたが、他の誰かがここで問題を抱えている場合に備えて、答えは次のとおりです。

LMock.Setup.WillReturn<TNullableInteger>(123).Any.WhenCalling.Id;
LMock.Setup.WillReturn<TNullableInteger>(456).Any.WhenCalling.ObjectId;
LMock.Setup.WillReturn<TNullableString>('blahblah').Any.WhenCalling.ObjectName;

これが他の誰かに役立つことを願っています;-)

于 2014-06-02T06:07:39.580 に答える