如何对功能参考的分配进行单元测试?

时间:2015-10-16 11:54:42

标签: unit-testing delphi reference equality

想象一下,我有一个这样的课程:

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

这很有道理。

无论如何,问题仍然存在:如何测试是否将字段中的函数分配给预期的工作,而不仅测试字段和函数是否在同一输入上返回相同的结果? < / p>

1 个答案:

答案 0 :(得分:0)

这些是使用reference to声明的引用方法类型。它们作为接口实现,由编译器自动创建和管理。

因此,您可以通过强制转换为接口并使用接口相等来测试相等性:

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

这有点粗糙,感谢Stefan Glienke的回答,告诉我如何: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创建了两个不同的匿名方法。理论上,编译器可以检测两个匿名方法在同一个上下文中调用相同的函数,并优化此代码以使用单个匿名方法。但编译器不这样做。