jwaliszko
jwaliszko

Reputation: 17064

Simulate ReflectionTypeLoadException being thrown during domain types collection

I'm able to collect all the types from the current domain calling this:

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

Assume no exception is thrown. Nevertheless I'd like to simulate ReflectionTypeLoadException to be thrown during that process.

How to corrupt any existing type in my code for this exception to occur?

Alternatively, if above cannot be achieved, how can I dynamically create an artificial assembly with some corrupted type to infect the domain (current or new)? In particular I'm looking for some clues regarding the implementation of the Infect() method below:

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

Upvotes: 1

Views: 218

Answers (1)

CodeNotFound
CodeNotFound

Reputation: 23210

This is for unit test purposes like you say by answered to my question in comments.

So why not move the logic that get all types in your current AppDomain assemblies to a class that implement a interface like the code below:

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();
    }
}

Use this interface in your code where the logic is called.

Then to simulate the exception ReflectionTypeLoadException for your unit tests just use Moq or any equivalent for that like I do below (i'm using Nunit for Assertions):

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());

Upvotes: 2

Related Questions