模拟在域类型收集期间引发的反射类型加载异常

本文关键字:类型 反射 加载 异常 模拟 | 更新日期: 2023-09-27 18:34:26

我能够从当前域中收集所有类型,调用以下内容:

var types = AppDomain.CurrentDomain
    .GetAssemblies()
    .SelectMany(x => x.GetTypes())
    .ToList();

假设未引发异常。尽管如此,我想模拟在这个过程中要抛出ReflectionTypeLoadException

如何损坏代码中的任何现有类型以发生此异常?

或者,如果无法实现上述目标,如何动态创建具有某些损坏类型的人工程序集以感染域(当前或新)?特别是,我正在寻找有关以下Infect()方法实现的一些线索:

Infect(AppDomain.CurrentDomain); // inject corrupted type
try
{
    var types = AppDomain.CurrentDomain
        .GetAssemblies()
        .SelectMany(x => x.GetTypes())
        .ToList();
}
catch (ReflectionTypeLoadException e)
{
    // done
}

模拟在域类型收集期间引发的反射类型加载异常

这是出于单元测试目的,就像您在评论中回答我的问题所说的那样。

那么,为什么不将获取当前 AppDomain 程序集中的所有类型的逻辑移动到实现接口的类中,如下所示的代码:

public interface ITypeProvider
{
    ICollection<Type> GetTypes();
}
public class AppDomainTypeProvider : ITypeProvider
{
    public ICollection<Type> GetTypes()
    {
        return AppDomain.CurrentDomain
            .GetAssemblies()
            .SelectMany(x => x.GetTypes())
            .ToList();
    }
}
public class MyAwesomeClassThatUseMyTypeProvider
{
    private readonly ITypeProvider _typeProvider;
    public MyAwesomeClassThatUseMyTypeProvider(ITypeProvider typeProvider)
    {
        _typeProvider = typeProvider;
    }
    public void DoSomething()
    {
        var types = _typeProvider.GetTypes();
    }
}

在调用逻辑的代码中使用此接口。

然后,要模拟单元测试的异常ReflectionTypeLoadException,只需使用 Moq 或任何等效项,如下所示(我使用 Nunit 进行断言):

var typeProviderMoq = new Mock<ITypeProvider>();
typeProviderMoq.Setup(p => p.GetTypes()).Throws(new ReflectionTypeLoadException(new [] { typeof(string)}, new[] { new Exception("test purpose") }));
var myAwesomeClass = new MyAwesomeClassThatUseMyTypeProvider(typeProviderMoq.Object);
Assert.Throws<ReflectionTypeLoadException>(() => myAwesomeClass.DoSomething());