Ric*_*ler 3 delphi mocking spring4d
使用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.谢谢.里克.
正确的代码应如下所示(不使用类型推断):
LMock.Setup.WillReturn<TNullableInteger>(123).Any.WhenCalling.Id;
LMock.Setup.WillReturn<TNullableInteger>(456).Any.WhenCalling.ObjectId;
LMock.Setup.WillReturn<TNullableString>('blahblah').Any.WhenCalling.ObjectName;
除了Rick已经给出的正确答案之外,还有一些解释为什么会这样:
原来的代码使用传递给WillReturn值类型推断,并推断其为ShortInt,SmallInt(编译器使用适合最小的签署序型)string.这些被存储为TValue并在调用方法时返回.但是然后RTTI尝试转换TValue为返回类型和失败的方法,因为它不知道如何转换a ShortInt或SmallInta Nullable<Integer>或a string到a,Nullable<string>因为TValue.TryCast不知道该Nullable<>类型的任何隐式运算符重载并且没有办法注册任何自定义转换器.
| 归档时间: | 
 | 
| 查看次数: | 632 次 | 
| 最近记录: |