使代码内部化,但可用于其他项目的单元测试

我们将所有的单元测试放在他们自己的项目中。我们发现,为了单元测试,我们必须使某些类公开,而不是仅仅使用内部类。有没有什么办法可以避免。使类公开而不是密封的内存含义是什么?

74334 次浏览

类可以是公共的,也可以是密封的。

但是,别这么做。

您可以创建一个反射内部类的工具,并发出一个通过反射访问所有内容的新类。MSTest 就是这样。

编辑: 我的意思是,如果您不想在原始程序集中包含任何测试内容; 如果成员是私有的,也可以这样做。

如果它是一个内部类,那么它一定不能单独使用。因此,除了测试内部使用该对象的其他类之外,您实际上不应该测试它。

正如您不应该测试类的私有成员一样,您也不应该测试 DLL 的内部类。这些类是一些公开可访问类的实现细节,因此应该通过其他单元测试来很好地执行。

其思想是,您只想测试类的行为,因为如果您测试内部实现细节,那么您的测试将是脆弱的。您应该能够在不破坏所有测试的情况下更改任何类的实现细节。

如果您发现确实需要测试该类,那么您可能首先需要重新检查为什么该类是内部的。

如果你吸毒的话。NET 中,InternalsVisibleTo程序集属性允许您创建“好友”程序集。这些程序集是特定的强名称程序集,允许访问内部类和其他程序集的成员。

注意,这应该谨慎使用,因为它会紧密耦合所涉及的程序集。InternalsVisibleTo 的一个常见用途是用于单元测试项目。由于上述原因,它可能不适合在实际的应用程序程序集中使用。

例如:

[assembly: InternalsVisibleTo("NameAssemblyYouWantToPermitAccess")]
namespace NameOfYourNameSpace
{

用于文件记录

也可以使用 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 核心应用程序中使用的方法。

  1. 添加 AssemblyInfo.cs文件并添加 [assembly: InternalsVisibleTo("AssemblytoVisible")]
  2. 将其添加到 。 csproj文件 (包含内部课程的项目)
<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/