【问题标题】:How to mock a function that has constant array and anonymous function as parameters如何模拟具有常量数组和匿名函数作为参数的函数
【发布时间】:2021-11-03 08:28:24
【问题描述】:

我有一个接口函数,它有一个常量数组和一个匿名函数作为参数:

  TCodeword = array[0..7] of Char;
  TIntFunc = reference to function: Integer;

  IMyInterface = interface(IInvokable)
    function DoSomething(const codeword: TCodeword; func: TIntFunc): Boolean;
  end;

我想模拟那个接口来测试一个正在使用它的对象:

  function IntFunc: Integer;
  begin
    Result := 5;
  end;  
     
  procedure Test;
  var
    MyInterfaceMock: Mock<IMyInterface>; 
    MyInterface: IMyInterface;
  begin
    MyInterfaceMock := Mock<IMyInterface>.Create(TMockbehavior.Strict);
    MyInterfaceMock.Setup.Returns(true).When.DoSomething(arg.IsAny<TCodeword>, arg.IsAny<TIntFunc>());
    
    MyInterface := MyInterfaceMock;
    MyInterface.DoSomething('12345678', IntFunc); 
  end;

运行时,设置时会引发 ENotSupportedException: ‚Type is not supported: TCodeword‘。 有人可以解释为什么这是不支持的类型吗?如何正确传递未指定的 TCodeword 来模拟该函数?

另外,我尝试在设置中传递显式参数:

  procedure Test;
  var
    MyInterfaceMock: Mock<IMyInterface>; 
    MyInterface: IMyInterface;
  begin
    MyInterfaceMock := Mock<IMyInterface>.Create(TMockbehavior.Strict);
    MyInterfaceMock.Setup.Returns(true).When.DoSomething('12345678', IntFunc);
    
    MyInterface := MyInterfaceMock;
    MyInterface.DoSomething('12345678', IntFunc); 
  end;

这样它将适用于常量数组,但不适用于匿名函数。我得到一个 EMockException: 'unexpected call of function DoSomething(const codeword: TCodeword; func: TIntFunc): Boolean with arguments: nil, (array)';

我怎样才能做到这一点?我很高兴有任何帮助!

【问题讨论】:

    标签: delphi spring4d


    【解决方案1】:

    有多个问题:

    1. 作为异常状态,不支持 TCodeword 类型 - 这是因为不支持 typeKind tkArray 的类型 - 我不记得确切原因是因为内部处理与 tkDynArray 非常相似。完成后,我将解决此问题并对此答案进行编辑。

    2. 当将常规函数传递给方法引用参数时,编译器会构建必要的代码以将常规函数包装到方法引用中,并且它使用接口对象来实现方法引用的接口(毕竟所有匿名方法都是只是接口)。但是,每次发生这种情况时都会这样做,这意味着将IntFunc 传递给TIntFunc 参数的两行是两个不同的指针。这就是参数匹配器在内部返回 False 的原因。如果您想避免这种情况,您需要将IntFunc 放入TIntFunc 类型的局部变量中并传递它。因为编译器只构建一次包装代码,并且在这两种情况下,局部变量的值都会传递给 DoSomething 调用。

    更新:已在开发分支中修复

    【讨论】:

      猜你喜欢
      • 2018-08-16
      • 1970-01-01
      • 1970-01-01
      • 2023-01-17
      • 2016-03-14
      • 1970-01-01
      • 2018-07-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多