[英]spring4d unregister interface type (spring4d, dunitx, delphi-mocks)
[英]Test in DUnitx with Delphi-Mocks passing private record
我是 DUnitx 和 Delphi-Mocks 的新手,所以請耐心等待。 我能找到的關於這個主題的唯一其他帖子是 3 年前的,而且沒有回答。 在 Delphi-Mocks 中返回記錄
德爾福里約熱內盧 10.3。 視窗 10
我想測試這個程序:
procedure TdmMariaDBConnection.Notify;
var
LViewModel : IPsViewModel;
begin
FMainViewModel.HandleCommands(FCommandRecord);
for LViewModel in FObservers do
LViewModel.HandleCommands(FCommandRecord);
end;
接口和記錄類型聲明為:
IPsView = interface(IInvokable)
['{F5532762-09F8-42C4-9F9F-A8F7FF7FA0C6}']
procedure HandleCommands(const Value: TPsCommandRecord);
procedure AfterCreate;
procedure BeforeDestroy;
end;
IPsViewModel = interface(IInvokable)
['{322DAB08-6A7C-4B61-B656-BC5346ACFC14}']
procedure HandleCommands(const Value: TPsCommandRecord);
end;
IPsMainViewModel = interface(IInvokable)
['{98FFB416-6C22-492F-BC85-D9A1ECA667FE}']
procedure Attach(const observer: IPsView);
procedure Notify;
procedure LoadFrame(const Value: TPanel);
procedure LoadForm(const Value: integer);
procedure LoadModalForm(const Value: integer);
procedure HandleCommands(const Value: TPsCommandRecord);
procedure SetViewFactory(Value: IPsViewFactory);
property ViewFactory: IPsViewFactory write SetViewFactory;
end;
TPsCommandRecord = record
CommandType: integer;
CommandObject: TObject;
CommandMessage: TPsTaskDialogMessageRecord;
end;
我在受保護的部分有通知程序
type
TdmMariaDBConnection = class(TDataModule, IPsModel)
procedure DataModuleDestroy(Sender: TObject);
procedure DataModuleCreate(Sender: TObject);
private
FObservers : TList<IPsViewModel>;
FMainViewModel : IPsMainViewModel;
FCommandRecord : TPsCommandRecord;
protected
procedure Notify;
….
end;
在我的測試項目中,我有一個后代
TTestabledmMariaDBConnection = class(TdmMariaDBConnection)
end;
var
CUT : TTestabledmMariaDBConnection;
procedure TTestModel_MariaDBConnection.Setup;
begin
CUT := TTestabledmMariaDBConnection.Create(nil);
end;
所以我可以調用受保護的方法。 到目前為止,我所擁有的是行不通的,因為我無法提供來自 TdmMariaDBConnection 的私有記錄實例,現在只關注 MainViewModel。
procedure TTestModel_MariaDBConnection.NotifyCallsMainViewModelHandleCommands;
var
MVMMock : TMock<IPsMainViewModel>;
LCommandRecord : TPsCommandRecord;
begin
//Arrange
MVMMock := TMock<IPsMainViewModel>.Create;
MVMMock.Setup.Expect.Once.When.HandleCommands(LCommandRecord);
//Act
CUT.Attach(MVMMock);
CUT.Notify;
//Assert
try
MVMMock.Verify();
Assert.Pass();
except on E: EMockException do
Assert.Fail(E.Message);
end;
end;
顯然 LCommandRecord 的添加是錯誤的我只是添加它們以使其編譯。 我需要(我認為)設置中測試類的記錄實例。 我嘗試添加一個函數來獲取它,但它也沒有用。
function TdmMariaDBConnection.GetCommandRecord: TPsCommandRecord;
begin
Result := FCommandRecord;
end;
MVMMock.Setup.Expect.Once.When.HandleCommands(CUT.GetCommandRecord);
測試甚至沒有完成,我在 TestInsight GUI 中得到一個不完整的圓圈,而不是希望的綠色檢查。
任何幫助,將不勝感激。 這也是 Verify 的正確用法嗎? 只能找到pass的時候什么都不做的解釋,那怎么加Assert呢?
在此先感謝加里
您設置模擬的方式將對傳遞的參數非常嚴格,並在調用 Verify 時檢查指定設置是否相等。
Delphi Mocks 中還有一個長期存在的問題,即記錄參數未正確比較是否相等(它們僅在參數位於完全相同的地址時才相等 - 請參閱SameValue
中的Delphi.Mocks.Helpers.pas
- 我知道這個問題是因為它我的代碼是在我的許可下使用的嗎——我前段時間寫了一個更好的版本,在 Spring4D 中使用,它也有 mocking fwiw)。 這就是為什么即使它不會與您添加的GetCommandRecord
一起運行,它也可能不會通過。
我通常建議人們在使用模擬時盡可能地寬容(到目前為止,我為 Delphi 編寫了 2 個模擬庫)。 幸運的是,Delphi Mocks 支持參數匹配器,它允許您指定實際上您並不關心傳遞的參數的確切值。
話雖如此,只需更改您的設置即可調用
MVMMock.Setup.Expect.Once.When.HandleCommands(It0.IsAny<TPsCommandRecord>);
這告訴內部匹配器記錄從 SUT 對模擬的調用,滿足期望的值並不重要。
順便說一句,出於與SameValue
錯誤類似的原因,它無法使用It0.IsEqualTo(LCommandRecord)
因為用於記錄的比較器在內部調用System.Generics.Defaults.Equals_Binary
,它只是對記錄進行平面內存比較,這可能任何引用類型都失敗。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.