2015-10-16 43 views
0

想象我有這樣一個類:函數引用的賦值如何進行單元測試?

type TFunctionWrapper<T1,T2> = class 
private 
    FFunc : TFunc<T1,T2>; 
public 
    constructor Create(AFunc : TFunc<T1,T2>); 
    function Apply(AValue : T1) : T2; 
end; 

與實施

constructor TFunctionWrapper<T1,T2>.Create(AFunc : TFunc<T1,T2>); 
begin 
    FFunc := AFunc; 
end; 

function TFunctionWrapper<T1,T2>.Apply(AValue : T1) : T2; 
begin 
    Result := FFunc(AValue); 
end; 

如何測試,如果分配的功能是一樣的嗎?函數引用不能與F1 = F2相提並論,因爲它導致一個編譯器錯誤:

[dcc32 Error] Project1.dpr(37): E2035 Not enough actual parameters

這使得相當不錯的感覺。

無論如何,問題仍然存在:如何測試是否將函數賦值給字段按預期工作,而不僅僅測試字段和函數是否在相同輸入上返回相同結果?

回答

0

這些是參考方法類型,用reference to聲明。它們被實現爲接口,由編譯器自動創建和管理。

所以,你可以通過轉換成一個接口,並使用接口平等測試相等:

IInterface(Pointer(@F1)^) = IInterface(Pointer(@F2)^) 

這是一個有點粗糙,並感謝斯特凡格林克的答案在這裏爲我展示瞭如何:https://stackoverflow.com/a/22645248/505088

但請注意,這可能無法提供您期望的結果。比如這個程序:

{$APPTYPE CONSOLE} 

uses 
    System.SysUtils; 

function Foo(Value: Integer): Integer; 
begin 
    Result := Value; 
end; 

var 
    F1, F2: TFunc<Integer, Integer>; 

begin 
    F1 := Foo; 
    F2 := Foo; 
    Writeln(IInterface(Pointer(@F1)^) = IInterface(Pointer(@F2)^)); 
    Readln; 
end. 

輸出FALSE。這是因爲編譯器爲F1F2創建了兩個不同的匿名方法。理論上,編譯器可以檢測到兩個匿名方法在相同的上下文中調用相同的函數,並優化此代碼以使用單個匿名方法。但編譯器不這樣做。

相關問題