【问题标题】:Delphi - Testing if events are assigned to methods, but without overriding for every delegate typeDelphi - 测试是否将事件分配给方法,但不覆盖每个委托类型
【发布时间】:2016-02-03 15:09:50
【问题描述】:

我必须在 Delphi 中对某些表单进行单元测试。我的老板希望我编写测试来检查是否分配了事件。太多了,我们必须对它们进行一些检查。

例如,我想检查一下

TMyForm.OnCreate = TMyForm.FormCreate.

为此,我写道:

function TFMaitreTest.SameMethod(const Method1, Method2: TNotifyEvent; msg : string = ''): boolean;
begin
Assert.IsTrue(TEqualityComparer<TNotifyEvent>.Default.Equals(Method1, Method2), msg);
end;

但是使用这种方式,我必须为每种事件委托覆盖SameMethod:TNotifyEvent、TDataSetEvent、...

然后我想到了使用泛型,例如:

function TFMaitreTest.SameMethod<T>(const Method1, Method2: T; msg : string = ''): boolean;

但这不会编译。 TEqualityComparer 需要一些通用约束,但不能为对象过程定义通用约束。使用TMethod 作为约束也不起作用。也许这里有办法,但我还没有找到。

然后,我想到了使用 Rtti 完全改变方法。我想比较使用 Rtti 的方法,但为此,我必须用字符串知道方法的名称。

RttiType.GetMethod(methodName)

这里,methodName 是一个纯字符串。如果我们重构并且methodName 变成MyMethod,我们有点搞砸了,必须手动检查使用该字符串的任何地方。我们希望有编译时错误。它更不容易出错。

C# 有 lambda 表达式的概念,这对于这些场景来说非常强大:

Get the name of a method using an expression

如何编写更通用的方法来测试事件属性是否分配给特定过程,而不必为每种事件类型编写方法?

感谢您的帮助。

【问题讨论】:

  • 我假设您使用的是 DUnitX,因为我发现了 Assert.IsTrue 的使用。那么Assert.AreEqual&lt;T&gt; 不做你想做的事吗?
  • @StefanGlienke 完全忽略了这个简单的解决方案。我快速测试了它,我认为它可以解决问题。请写下这个答案,以便我接受。

标签: unit-testing delphi generics


【解决方案1】:

由于您使用的是 DUnitX Assert 类型,因此您应该使用它的 AreEqual&lt;T&gt; 方法,该方法完全符合您的要求 - 您必须指定泛型类型参数,并且不能让编译器推断它:

Assert.AreEqual<TNotifyEvent>(myForm.OnCreate, myForm.FormCreate);

【讨论】:

  • 另一种不必使用泛型的替代方法是使用 RTTI 检索分配给对象事件的当前值,然后如果该值被分配给方法(将值类型转换为 @ 987654324@ 并检查其 Code 字段是否不为零),然后使用 RTTI 检索方法的名称并检查它是否与您所需的方法名称相同,并检查 TMethod.Data 字段是否指向所需的对象。
猜你喜欢
  • 2012-12-24
  • 2023-04-10
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-25
相关资源
最近更新 更多