Как воспроизводимо вызвать / спровоцировать ReflectionTypeLoadException? - PullRequest
3 голосов
/ 23 августа 2011

К сожалению, ссылки на это исключение обычно носят экзотический характер и могут произойти, когда вы, например, перечислите типы через Assembly.GetTypes() - в данном случае это происходит в одном из наших развертываний, но тот же набор сборок отлично работает на сервере интеграции.

Чтобы защититься от ошибок такого типа, я хотел бы иметь возможность спровоцировать такое исключение, чтобы проверить, работает ли мой код обработки исключений как ожидалось.

Следовательно, любые указатели были бы полезны, например, просто зная, что за причины этого исключения.

EDIT Моя попытка до сих пор:

  • Определить тип в сборке A, который использует атрибут сборки B
  • Иметь некоторый код для всех типов в сборке, где указано атрибут указан.
  • Я создаю атрибут только тогда, когда флаг DEBUG имеет значение true
  • Затем я копирую сборку выпуска этой зависимости в соответствующую папку

Но мне удается получить TypeLoadException только с довольно четким сообщением об ошибке

Ответы [ 2 ]

3 голосов
/ 23 августа 2011

Следующее вызывает это исключение:

У вас есть сборка A, которая определяет следующий класс:

public class AC
{
    public BC GetBC() { /* ... */ }
}

У вас есть сборка B, которая определяет класс BC.Теперь, когда вы загружаете сборку A и получаете члены класса AC, например, используя assembly.GetTypes().SelectMany(t => t.GetMembers()).ToList();, платформа пытается разрешить BC.Он даже знает, что он в сборке B.Однако, если инфраструктура разрешает сборку B, которая не содержит BC, будет выброшено TypeLoadException.Это может произойти, если сборка B не обновлена, поскольку вы забыли ее в своем развертывании.

ОБНОВЛЕНИЕ:
Чтобы получить ReflectionTypeLoadException,сценарий очень похож.Однако вам не нужно иметь метод в AC, который возвращает BC, но вам нужно извлечь AC из BC:

public class AC : BC
{
}

Используя свойство LoaderExceptions, выможет извлечь исключения, которые приводят к этому ReflectionTypeLoadException.В моем случае это TypeLoadException с указанием типа, который он не может загрузить.

2 голосов
/ 23 августа 2011

Другой подход, если вы хотите проверить, как ваш код обрабатывает исключение, заключается в использовании в вашем тестировании макетов. С помощью насмешек вы можете смоделировать подсистему загрузки сборок и сконцентрироваться на тестировании того, как вы обрабатываете возникающее исключение - гораздо проще.

При использовании насмешки вы бы использовали IAssemblyService вместо прямого вызова GetTypes на Assembly. В своем макете вы можете выбросить необходимое исключение. Более обычно использовать фальшивый фреймворк, такой как FakeItEasy, но в следующем для демонстрации используется скрученный вручную макет.

В своем тесте вы заменили бы свою реальную службу сборки на MockAssemblyService.

internal class MyTypeThatLoadsStuff
{
    public MyTypeThatLoadsStuff(IAssemblyService assemblyService)
    {
        //Do stuff with assemblyService
    }
}

internal interface IAssemblyService
{
    IEnumerable<Type> GetTypes();
}

internal class AssemblyService : IAssemblyService
{
    private readonly Assembly _assembly;

    public AssemblyService(Assembly assembly)
    {
        _assembly = assembly;
    }

    public IEnumerable<Type> GetTypes()
    {
        return _assembly.GetTypes();
    }
}

internal class MockAssemblyService : IAssemblyService
{
    public IEnumerable<Type> GetTypes()
    {
        throw new ReflectionTypeLoadException();
    }
}

И с насмешливой структурой, такой как FakeItEasy:

[Test]
public void Test()
{
    IAssemblyService service = A.Fake<IAssemblyService>();

    ReflectionTypeLoadException ex = new ReflectionTypeLoadException(
        new[] { typeof(SprocketTests) }, new[] { new Exception() });

    A.CallTo(() => service.GetTypes()).Throws(ex);

    MyTypeThatLoadsStuff loader = new MyTypeThatLoadsStuff(service);

    //test...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...