2015-10-16 69 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创建了两个不同的匿名方法。理论上,编译器可以检测到两个匿名方法在相同的上下文中调用相同的函数,并优化此代码以使用单个匿名方法。但编译器不这样做。

相关问题