是否可以在不将测试代码标记为内部代码的情况下测试内部代码?

Can internal code be tested without having to mark the test code as internal?

我有一个 F# 库,其中包含许多我想测试的非 public 内容。目前,所有不属于程序集 public API 的代码都标记为 internal(具体来说,它位于标记为 internal 的模块中)。我使用 InternalsVisibleToAttribute 使此代码对我的测试程序集可见。但是,为了让测试程序集能够编译,所有在其签名中使用内部类型的测试(其中大部分,因为我使用 FsCheck 自动生成测试输入)也必须标记为内部(这需要应用于每个函数,因为内部模块不会被 xunit 发现)。此外,任何专用于 FsCheck 生成的类型(例如 type ValidCustomer = ValidCustomer of Customer,其中 Customer 是我的内部域类型)也需要标记为内部,并且 FsCheck 在创建内部类型时似乎会​​卡住,因此测试不会't 运行.

有没有什么方法可以测试内部 F# 代码(来自单独的测试程序集)而不必将其签名依赖于内部类型的所有测试标记为内部?现在我只是倾向于在原始代码中根本不做任何内部操作,但理想情况下,有一种方法可以让我的干净 API 蛋糕也吃掉。

我发现 OO 世界通常非常反对尝试直接测试任何东西 internal/private。

在函数世界中,我看到更多的趋势是只公开 public 不打算用于 public 的函数,以便对其进行测试。看到这个 comment from Edward Kmett.

When I started writing Haskell I started rethinking the way I used to approach encapsulation and hiding.

...

In general I'm a big fan of exposing all of the salient details, constructors and all for my data types through some kind of .Internal module, even if I want encapsulation and safety in the rest of the API.

...

As a side-effect of that you can then use these newly exposed guts to do nice testing. =)

原来的评论里有很多细节,还有一个谈话他详细讨论了这个,但我现在找不到了。

您也可以给模块起一个非常丑陋的名字,例如 __INTERNAL__ 以阻止其使用。