打破测试功能的 Ada 隐私

Breaking Ada privacy for Test functions

假设我有两个包裹:

with Ada.Streams; use Ada.Streams;
package P is
   type SEA is new Stream_Element_Array (1..4);
   function foo (Input : in SEA) return Natural;
private
   type PRecord is record
      Bar : Natural := 0;
   end record;
   function To_PRecord is new Ada.Unchecked_Conversion
     (Source => SEA,
      Target => PRecord);
end P;
------
package body P is
   function foo (Input : in SEA) return Natural
   is
      Tmp : constant PRecord := To_PRecord (Input);
   begin
      return Tmp.Bar;
   end foo;
end P;

-- Say SEA was defined in a third package and is accessible
package Q is
   function foo (Input : SEA) return Natural;
end P;
-----
with P;
package body Q is
   function foo (Input : SEA) return Natural
   is
   begin
      return P.foo(Input);
   end foo;
end Q;

包 P 很容易测试:

with AUnit.Assertions; use AUnit.Assertions;
package body P.Tests is
   function To_SEA is new Ada.Unchecked_Conversion
     (Source => PRecord,
      Target => SEA);

   procedure Test_Foo
   is
      Input : PRecord := (Bar => 42);
   begin
      Assert (foo(To_SEA (Input)) = 42, "foo failed miserably");
   end Test_Foo;
end P.Tests;

但是我该如何测试 Q? PRecord 无法访问。因此,我看不出 Q 如何在不改变我正在测试的代码的情况下进行测试。在 C++ 中,我会将包 Q.Tests 定义为 Pfriend 并获得访问权限。

我想我可以在 PQ.Tests 可以使用的包中定义 PRecord 但是有没有不需要更改 P 或 Q 的解决方案(因为我真的不喜欢为了测试而需要更改生产代码。

子包 P.Spy 可以看到整个 P 的规范; Q.Tests 可以调用它来进行验证检查。

根据 Simon Wright 的回答,可以定义 P.Spy 包如下:

package P.Spy is
   function Create (Bar : in Natural) return SEA;
private
   function To_SEA is new Ada.Unchecked_Conversion (Source => PRecord,Target => SEA);
end P.Spy;
---
package body P.Spy is
   function Create (Bar : in Natural) return SEA
   is
      Result : PRecord;
   begin 
      Result.Bar := Bar;
      return To_SEA (Result);
   end Create;
end P.Spy;

允许 Q.Tests 测试其 public 接口的能力。