我正在努力用 DUnit 成功模拟 Spring4d 事件。
事实上,我更多的是嘲笑一个模拟返回一个事件的模拟......
这是基本结构。
TMyObject --EventContainer--> TMock<IEventContainer> --Event--> TMock<IEvent>
TMyObject 有一个属性 EventContainer : IEventContainer
IEventContainer 有一个属性 Event : IMyEvent
我想嘲讽
MyObject.EventContainer.Event.Add
我测试了我能想到的每一种可能性。我要么得到 AV,要么得到无效的演员表。我把源代码放在下面。如果有人可以帮助我完成这项工作,那就太好了!
program Project2;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
DUnitTestRunner,
Spring.Events,
Spring,
Classes,
TestFramework,
Delphi.Mocks;
//Unit1 in 'Unit1.pas';
type
{$M+}
IMyEvent = interface(IEvent<TNotifyEvent>)
procedure Add(const handler: TMethod);
end;
{$M-}
{$M+}
IMyEventMock = interface(IMyEvent)
procedure Add(const handler: TMethod);
end;
{$M-}
{$M+}
IEventContainer = interface(IInterface)
function GetEvent: IMyEvent;
procedure SetEvent(const Value: IMyEvent);
property Event: IMyEvent
read GetEvent
write SetEvent;
end;
{$M-}
{$M+}
ITestEventContainer = interface(IEventContainer)
function GetEvent: TMock<IMyEvent>;
procedure SetEvent(const Value: TMock<IMyEvent>);
property Event: TMock<IMyEvent>
read GetEvent
write SetEvent;
end;
{$M-}
{$REGION 'TEventContainer'}
TEventContainer = class(TInterfacedObject, IEventContainer)
private
FAEvent: IMyEvent;
function GetEvent: IMyEvent;
procedure SetEvent(const Value: IMyEvent);
public
property Event: IMyEvent
read GetEvent
write SetEvent;
end;
{$ENDREGION}
{$REGION 'TMyObject'}
TMyObject = class(TObject)
private
FEventContainer: IEventContainer;
function GetEventContainer: IEventContainer;
procedure SetEventContainer(const Value: IEventContainer);
public
property EventContainer: IEventContainer
read GetEventContainer
write SetEventContainer;
end;
{$ENDREGION}
{$REGION 'TMyObjectTest'}
TMyObjectTest = class(TTestCase)
strict private
FMyObject: TMyObject;
FMyEventContainerMock: TMock<IEventContainer>;
FMyTestEventContainerMock: TMock<ITestEventContainer>;
FEventMock: TMock<IMyEventMock>;
public
procedure SetUp; override;
procedure TearDown; override;
published
procedure Test_InstanceAsValue;
procedure Test_Value_Make;
procedure Test_Value_From;
procedure Test_Value_From_Instance;
procedure Test_Value_From_Variant;
procedure Test_Value_From_Variant_Instance;
procedure Test_Mocked_Container_Value_Make;
procedure Test_Mocked_Container_Value_From;
procedure Test_Mocked_Container_Value_From_Instance;
procedure Test_Mocked_Container_Value_From_Variant;
procedure Test_Mocked_Container_Value_From_Variant_Instance;
end;
{$ENDREGION}
{$REGION 'TEventContainer'}
function TEventContainer.GetEvent: IMyEvent;
begin
Result := FAEvent;
end;
procedure TEventContainer.SetEvent(const Value: IMyEvent);
begin
FAEvent := Value;
end;
{$ENDREGION}
{$REGION 'TMyObject'}
function TMyObject.GetEventContainer: IEventContainer;
begin
Result := FEventContainer;
end;
procedure TMyObject.SetEventContainer(const Value: IEventContainer);
begin
FEventContainer := Value;
end;
{$ENDREGION}
{$REGION 'TMyObjectTest'}
procedure TMyObjectTest.SetUp;
begin
inherited;
FMyObject := TMyObject.Create;
FMyEventContainerMock := TMock<IEventContainer>.Create;
FMyObject.EventContainer := FMyEventContainerMock;
end;
procedure TMyObjectTest.TearDown;
begin
inherited;
FMyObject.Free;
FMyObject := nil;
end;
procedure TMyObjectTest.Test_Value_Make;
var aValue : TValue;
begin
FEventMock := TMock<IMyEventMock>.Create;
TValue.Make(@FEventMock, TypeInfo(IMyEventMock), aValue);
FMyEventContainerMock.SetUp.WillReturnDefault('GetEvent', aValue);
FMyObject.EventContainer.Event;
end;
procedure TMyObjectTest.Test_InstanceAsValue;
begin
FEventMock := TMock<IMyEventMock>.Create;
FMyEventContainerMock.SetUp.WillReturnDefault('GetEvent', FEventMock.InstanceAsValue);
FMyObject.EventContainer.Event;
end;
procedure TMyObjectTest.Test_Mocked_Container_Value_From;
begin
FMyTestEventContainerMock := TMock<ITestEventContainer>.Create;
FMyObject.EventContainer := FMyTestEventContainerMock;
FEventMock := TMock<IMyEventMock>.Create;
FMyTestEventContainerMock.SetUp.WillReturnDefault('GetEvent', FEventMock.InstanceAsValue);
FMyObject.EventContainer.Event;
end;
procedure TMyObjectTest.Test_Mocked_Container_Value_From_Instance;
begin
FMyTestEventContainerMock := TMock<ITestEventContainer>.Create;
FMyObject.EventContainer := FMyTestEventContainerMock;
FEventMock := TMock<IMyEventMock>.Create;
FMyTestEventContainerMock.SetUp.WillReturnDefault('GetEvent', TValue.From(FEventMock));
FMyObject.EventContainer.Event;
end;
procedure TMyObjectTest.Test_Mocked_Container_Value_From_Variant;
begin
FMyTestEventContainerMock := TMock<ITestEventContainer>.Create;
FMyObject.EventContainer := FMyTestEventContainerMock;
FEventMock := TMock<IMyEventMock>.Create;
FMyTestEventContainerMock.SetUp.WillReturnDefault('GetEvent', TValue.FromVariant(FEventMock));
FMyObject.EventContainer.Event;
end;
procedure TMyObjectTest.Test_Mocked_Container_Value_From_Variant_Instance;
begin
FMyTestEventContainerMock := TMock<ITestEventContainer>.Create;
FMyObject.EventContainer := FMyTestEventContainerMock;
FEventMock := TMock<IMyEventMock>.Create;
FMyTestEventContainerMock.SetUp.WillReturnDefault('GetEvent', TValue.FromVariant(FEventMock.Instance));
FMyObject.EventContainer.Event;
end;
procedure TMyObjectTest.Test_Mocked_Container_Value_Make;
var aValue : TValue;
begin
FMyTestEventContainerMock := TMock<ITestEventContainer>.Create;
FMyObject.EventContainer := FMyTestEventContainerMock;
FEventMock := TMock<IMyEventMock>.Create;
TValue.Make(@aValue, TypeInfo(TMock<IMyEventMock>), aValue);
FMyTestEventContainerMock.SetUp.WillReturnDefault('GetEvent', aValue);
FMyObject.EventContainer.Event;
end;
procedure TMyObjectTest.Test_Value_From;
begin
FEventMock := TMock<IMyEventMock>.Create;
FMyEventContainerMock.SetUp.WillReturnDefault('GetEvent', TValue.From(FEventMock));
FMyObject.EventContainer.Event;
end;
procedure TMyObjectTest.Test_Value_From_Instance;
begin
FEventMock := TMock<IMyEventMock>.Create;
FMyEventContainerMock.SetUp.WillReturnDefault('GetEvent', TValue.From(FEventMock.Instance));
FMyObject.EventContainer.Event;
end;
procedure TMyObjectTest.Test_Value_From_Variant;
begin
FEventMock := TMock<IMyEventMock>.Create;
FMyEventContainerMock.SetUp.WillReturnDefault('GetEvent', TValue.FromVariant(FEventMock));
FMyObject.EventContainer.Event;
end;
procedure TMyObjectTest.Test_Value_From_Variant_Instance;
begin
FEventMock := TMock<IMyEventMock>.Create;
FMyEventContainerMock.SetUp.WillReturnDefault('GetEvent', TValue.FromVariant(FEventMock.Instance));
FMyObject.EventContainer.Event;
end;
begin
RegisterTest(TMyObjectTest.Suite);
try
DUnitTestRunner.RunRegisteredTests;
ReadLn;
except
on E: Exception do
begin
Writeln(E.ClassName, ': ', E.Message);
ReadLn;
end;
end;
end.