2017-10-04 101 views
4

我有一个F#库,里面有很多我想测试的非公开内容。目前,所有不属于程序集公共API的代码都标记为internal(具体来说,它放置在标记为internal的模块中)。我使用InternalsVisibleToAttribute使此代码对我的测试程序集可见。然而,为了让测试程序集编译,在签名中使用内部类型的所有测试(其中大部分是因为我使用FsCheck来自动生成测试输入)也必须标记为内部(这需要应用于每个函数,因为内部模块不会被xunit发现)。此外,任何专门用于FsCheck生成的类型(例如,type ValidCustomer = ValidCustomer of Customer,其中Customer是我的内部域类型)也需要标记为内部类型,并且在创建内部类型时FsCheck似乎会卡住,因此测试无法运行。可以测试内部代码而不必将测试代码标记为内部代码?

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

+1

为什么你的*域*类型是内部的?除非您使用与[DDD](http://amzn.to/WBCwx7)大不相同的术语,否则域模型是您的应用程序中最重要的部分。这是应用程序首先存在的原因... –

+0

@MarkSeemann或许*域类型*是错误的术语。在这种特殊情况下,它是一个单独的项目,它从数据仓库数据库中读取数据,汇总销售数据等,并将这些数据公开给Web API。 API主要获取数字数据,但是有很多内部的,很好的域类型(客户,订单等等 - 他们正在对域进行建模,尽管它们不在本项目之外使用),用于生成汇总数据。 – cmeeren

+0

好的,但是使这些类型成为内部的动机是什么? –

回答

2

我发现OO世界通常会非常反对尝试直接测试任何内部/私有内容。

在功能世界中,我已经看到更多倾向于公开使用不公开的公共功能,因此可以对其进行测试。看到这个comment from Edward Kmett

当我开始编写Haskell时,我开始重新思考我用来处理封装和隐藏的方式。

...

总的来说,我露出全部显着细节,构造和所有为我的数据类型,通过某种。内部模块的大风扇,即使我想封装和安全API的其余部分。

...

由于你就可以使用这些新暴露出来的胆量做很好的测试副作用。 =)

在原始评论中有很多更多的细节,并且有一个讨论,他详细讨论了这个问题,但我现在找不到它。

你也可以给模块一个非常难看的名字,如__INTERNAL__,以阻止它的使用。