【发布时间】:2010-09-11 12:53:54
【问题描述】:
我们将所有单元测试都放在他们自己的项目中。我们发现我们必须将某些类公开而不是仅用于单元测试的内部类。无论如何要避免这样做。公开类而不是密封类对内存的影响是什么?
【问题讨论】:
标签: c# unit-testing scope
我们将所有单元测试都放在他们自己的项目中。我们发现我们必须将某些类公开而不是仅用于单元测试的内部类。无论如何要避免这样做。公开类而不是密封类对内存的影响是什么?
【问题讨论】:
标签: c# unit-testing scope
如果您使用的是 .NET,InternalsVisibleTo 程序集属性允许您创建“朋友”程序集。这些是特定的强命名程序集,允许访问其他程序集的内部类和成员。
注意,这应该谨慎使用,因为它会紧密耦合所涉及的程序集。 InternalsVisibleTo 的一个常见用途是用于单元测试项目。由于上述原因,在您的实际应用程序集中使用它可能不是一个好的选择。
示例:
[assembly: InternalsVisibleTo("NameAssemblyYouWantToPermitAccess")]
namespace NameOfYourNameSpace
{
【讨论】:
如果它是一个内部类,那么它一定不能被孤立地使用。因此,除了测试其他在内部使用该对象的类之外,您不应该真正对其进行测试。
正如您不应该测试类的私有成员一样,您也不应该测试 DLL 的内部类。这些类是某些可公开访问的类的实现细节,因此应该通过其他单元测试很好地进行练习。
这个想法是您只想测试一个类的行为,因为如果您测试内部实现细节,那么您的测试将会很脆弱。您应该能够在不破坏所有测试的情况下更改任何类的实现细节。
如果您发现您确实需要测试该类,那么您可能需要重新检查为什么该类首先是内部的。
【讨论】:
用于文档目的
您也可以使用Type.GetType 方法实例化内部类
例子
//IServiceWrapper is public class which is
//the same assembly with the internal class
var asm = typeof(IServiceWrapper).Assembly;
//Namespace.ServiceWrapper is internal
var type = asm.GetType("Namespace.ServiceWrapper");
return (IServiceWrapper<T>)Activator
.CreateInstance(type, new object[1] { /*constructor parameter*/ });
对于泛型类型,有如下不同的处理:
var asm = typeof(IServiceWrapper).Assembly;
//note the name Namespace.ServiceWrapper`1
//this is for calling Namespace.ServiceWrapper<>
var type = asm.GetType("Namespace.ServiceWrapper`1");
var genType = type.MakeGenericType(new Type[1] { typeof(T) });
return (IServiceWrapper<T>)Activator
.CreateInstance(genType, new object[1] { /*constructor parameter*/});
【讨论】:
以下是在 .NET Core 应用程序中使用的方法。
[assembly: InternalsVisibleTo("AssemblytoVisible")]
<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
<_Parameter1>Test_Project_Name</_Parameter1> <!-- The name of the project that you want the Internal class to be visible To it -->
</AssemblyAttribute>
</ItemGroup>
更多信息请关注https://improveandrepeat.com/2019/12/how-to-test-your-internal-classes-in-c/
【讨论】:
类既可以是公开的也可以是密封的。
但是,不要那样做。
您可以创建一个工具来反射内部类,并发出一个通过反射访问所有内容的新类。 MSTest 会这样做。
编辑:我的意思是,如果您不想在原始程序集中包含任何测试内容;如果成员是私有的,这也有效。
【讨论】:
public sealed class?你对那颗宝石的理由是什么?