.net - InternalsVisibleTo 的替代方案

标签 .net unit-testing internalsvisibleto

我目前正在尝试在我的解决方案中编写单元测试,但我想将我的单元测试放在不同的单独项目中。问题是当我生成一些假测试数据时,我需要设置类的属性,但这是不可能的,因为属性具有私有(private)/内部设置。 我找到了一种使用属性仅向某些项目公开内部属性的方法 InternalsVisibleTo,这效果很好,但看起来有点困惑和不干净。我正在寻找更离散的方式将我的私有(private)属性(property)暴露给其他项目。例如,也许有一种方法可以公开我的属性,而无需在我的域类中显式添加属性? 知道我该怎么做吗?

编辑:我发现这篇关于在 csproj 文件中设置 InternalsVisibleTo 的文章。有人用过这个吗? https://bartwullems.blogspot.com/2020/06/internalsvisibleto-in-your-csproj-file.html

最佳答案

this blog post 中描述了一种替代方案示例代码位于 GitHub ,它使用一个未记录的属性在访问私有(private)/内部成员的程序集中使用。

但请注意以下几点:

  • 这没有记录,也不推荐
  • 不能直接编译,需要使用Roslyn
  • 它似乎甚至会忽略对私有(private)成员的访问,这绝对是需要非常小心的事情

但是,例如在处理动态程序集等时,它可能很有用,请参见下面的示例。

代码

这是需要完成的操作,在您的代码中添加 IgnoresAccessChecksToAttribute ,如以下代码所示(确保它不在任何其他命名空间下,否则它将不起作用):

namespace System.Runtime.CompilerServices
{
    [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
    public class IgnoresAccessChecksToAttribute : Attribute
    {
        public IgnoresAccessChecksToAttribute(string assemblyName)
        {
            AssemblyName = assemblyName;
        }

        public string AssemblyName { get; }
    }
}

然后在代码中的任意位置添加属性,如下所示:

[assembly: IgnoresAccessChecksTo("AssemblyToAccess")]

或在 csproj 文件中:

<ItemGroup>
  <AssemblyAttribute Include="System.Runtime.CompilerServices.IgnoresAccessChecksToAttribute">
     <_Parameter1>AssemblyToAccess</_Parameter1>
   </AssemblyAttribute>
</ItemGroup>

编译

编译很棘手,因为它不能用标准方法编译,而是必须通过 Roslyn 调用,应该有很多资源可以帮助您了解如何使用 Roslyn 进行动态编译,但这里是需要完成的特定细节此编译工作:

var compilationOptions = new CSharpCompilationOptions(OutputKind.ConsoleApplication).
            WithMetadataImportOptions(MetadataImportOptions.All);

var topLevelBinderFlagsProperty = typeof(CSharpCompilationOptions)
        .GetProperty("TopLevelBinderFlags", BindingFlags.Instance | BindingFlags.NonPublic);

// 22 is the value of the undocumented member BinderFlags.IgnoreAccessibility
topLevelBinderFlagsProperty.SetValue(compilationOptions, (uint)1 << 22);

装配生成器中的用法

一种合法用途是在动态编译需要访问内部类的程序集时,请参阅 my answer there示例代码。

关于.net - InternalsVisibleTo 的替代方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66007077/

相关文章:

java - Java 中比较器的 JUnit 测试

.net - InternalsVisibleTo 不适用于托管 C++

c# - 如何通过安全地签署公共(public) token key 来使 InternalsVisibleTo 属性起作用?

c# - 为什么要等待异步 Web 服务调用

c# - 为什么 ServerVariables ["HTTP_REFERER"] 跳过一个页面?

AngularJS $http 模拟响应(...): how to mock a `location` header in the response?

unit-testing - Controller 单元测试 (Symfony)

c# - Entity Framework 中实体的内部访问使得查询崩溃时的简单 linq

c# - 编译错误,.NET 没有看到存在的函数

c# - 是否可以更改异步方法的任务创建选项?