当前位置:  开发笔记 > 编程语言 > 正文

进行单元测试时的C#"内部"访问修饰符

如何解决《进行单元测试时的C#"内部"访问修饰符》经验,为你挑选了5个好方法。

我是单元测试的新手,我正在试图弄清楚是否应该开始使用更多的"内部"访问修饰符.我知道如果我们使用'internal'并设置汇编变量'InternalsVisibleTo',我们可以测试我们不想从测试项目声明公共的函数.这让我觉得我应该总是使用'​​内部',因为至少每个项目(应该?)都有它自己的测试项目.你们能告诉我为什么不这样做吗?我什么时候应该使用'私人'?



1> EricSchaefer..:

需要测试内部类,并且有一个assemby属性:

using System.Runtime.CompilerServices;

[assembly:InternalsVisibleTo("MyTests")]

将其添加到项目信息文件中,例如Properties\AssemblyInfo.cs.


这应该是公认的答案.我不了解你们,但是当他们测试的代码"太远"时,我会感到紧张.我完全是为了避免测试标记为"私有"的东西,但是太多的"私有"东西可能很好地指向一个正在努力被提取的"内部"类.TDD或没有TDD,我更喜欢测试大量代码的测试,而不是少量测试可以运行相同数量的代码.并且避免测试"内部"东西并不能完全帮助实现良好的比例.
将其添加到测试项目中(例如,在Properties\AssemblyInfo.cs中)."MyTests"将成为测试组件.
包装和`#if DEBUG`,`#endif`块只在调试版本中启用此选项.
这是正确的答案.任何答案都说只有公共方法应该进行单元测试才会错过单元测试和借口.功能测试是面向黑盒的.单元测试是面向白盒的.他们应该测试功能的"单位",而不仅仅是公共API.
有一个很棒的[讨论](http://lostechies.com/derickbailey/2014/01/03/semantics-modules-and-testing-why-and-how-i-test-internal-components-not-private-methods /)在@DerickBailey和Dan Tao之间继续讨论**内部**和**私有**之间的语义差异以及测试_internal_组件的必要性.非常值得一读.
对于.NET Core - 将其添加到应用程序中的任何.cs文件.详情请见/sf/ask/17360801/
我是将它添加到测试项目还是测试项目中??!?
@Marjan是的,除非您对强化名称签署程序集并将密钥包含在InternalsVisibleTo属性中.请参阅http://adelkhalil.bloggingabout.net/2007/10/12/tiny-tip-improve-security-with-internalsvisibleto-attribute/我想这取决于你的偏执程度.
谢谢Eric.一整天都在寻找那个选项.
我使用#if RELEASE指令包装了这个属性,因此内部版本对于发布版本中的任何内容都不可见.只是一个想法.
亚历克斯·克劳斯(Alex Klaus)补充说。我只是花了一些时间来寻找。.NET Core足够新,问题需要一个新的答案。

2> Brian Rasmus..:

如果你想测试私有方法,看一看PrivateObject,并PrivateTypeMicrosoft.VisualStudio.TestTools.UnitTesting命名空间.它们围绕必要的反射代码提供易于使用的包装器.

文档: PrivateType,PrivateObject


这个答案是愚蠢的投票.它指出了一种新的解决方案和一种前所未有的非常好的解决方案.
投票时请发表评论.谢谢.

3> gldraphael..:

除Eric的答案外,您还可以在csproj文件中进行配置:


    
      <_Parameter1>MyTests
    

或者,如果每个要测试的项目都有一个测试项目,则可以在Directory.Build.props文件中执行以下操作:


    
      <_Parameter1>$(MSBuildProjectName).Test
    

参见:https : //stackoverflow.com/a/49978185/1678053
示例:https : //github.com/gldraphael/evlog/blob/master/Directory.Build.props#L5-L12



4> Steven Behnk..:

您也可以使用私有,您可以使用反射调用私有方法.如果您使用的是Visual Studio Team Suite,它有一些很好的功能,可以生成一个代理来为您调用私有方法.这是一个代码项目文章,演示了如何自己完成工作以对私有和受保护方法进行单元测试:

http://www.codeproject.com/KB/cs/testnonpublicmembers.aspx

就您应该使用的访问修饰符而言,我的一般经验法则是私有,并根据需要升级.这样,您将尽可能少地公开您的类的内部细节,它有助于保持实现细节隐藏,就像它们应该的那样.



5> Jon Skeet..:

默认情况下继续使用私有.如果成员不应暴露在该类型之外,则不应暴露在该类型之外,即使是在同一项目中也是如此.这样可以使事情变得更加安全和整洁 - 当您使用该对象时,您可以使用哪种方法更清晰.

话虽如此,我认为有时将自然私有方法内部用于测试目的是合理的.我更喜欢使用反射,这是重构 - 不友好.

要考虑的一件事可能是"ForTest"后缀:

internal void DoThisForTest(string name)
{
    DoThis(name);
}

private void DoThis(string name)
{
    // Real implementation
}

然后,当您在同一个项目中使用该类时,很明显(现在和将来)您不应该真正使用此方法 - 它仅用于测试目的.这有点hacky,而不是我自己做的事情,但它至少值得考虑.


我偶尔会使用`ForTest`方法但我总觉得它很难看(添加代码在生产业务逻辑方面没有提供任何实际价值).通常我发现我必须使用这种方法,因为设计很不幸(即必须在测试之间重置单例实例)
@CADbloke:你的意思是制作*方法*内部而不是私有?不同之处在于,你真的希望*它是私有的.你的生产代码库中用`ForTest`调用方法的任何代码*显然是错误的,而如果你只是将方法设为内部,那么它看起来好像可以使用.
如果该方法是内部方法,这是否不排除将其用于测试程序集?
@CADbloke:您可以在发布版本中排除单个方法,就像使用部分类IMO一样容易.如果你*做*那么,它表明你没有针对你的发布版本运行测试,这对我来说听起来不错.
推荐阅读
kikokikolove
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有