Visual Studio 2015 InvalidProgramException в модульном тесте с подделками
Я использую Visual Studio 2015 Enterprise RTM для написания модульных тестов для проекта, который использует Unity Container.
Я обнаружил, что простого акта добавления фальшивой сборки для Unity, даже не используя фальшивку, достаточно для генерации этого исключения:
System.InvalidProgramException: Common Language Runtime обнаружил недопустимую программу.
Рассмотрим следующие шаги для воспроизведения:
С помощью Visual Studio 2015 Enterprise RTM создайте проект модульного тестирования с ориентацией на.NET 4.6
Добавить пакет NuGet "Unity" версии 3.5.1404.0
Добавьте пакет NuGet "CommonServiceLocator" версии 1.2.0
Напишите один модульный тест примерно так:
[TestClass]
public class UnitTest1 : IDisposable
{
[TestMethod]
public void TestMethod1()
{
new ResolvedArrayParameter<IDisposable>(new IDisposable[] {this});
}
void IDisposable.Dispose()
{
}
}
Проверьте прохождение теста
Щелкните правой кнопкой мыши ссылку Microsoft.Practices.Unity и выберите "Добавить сборку подделок".
Перезапустите тест
Обратите внимание на следующую замечательную ошибку теста:
Название теста: TestMethod1
Тестирование полного имени: UnitTestProject11.UnitTest1.TestMethod1
Источник теста: c:\temp\UnitTestProject11\UnitTestProject11\UnitTest1.cs: строка 12
Результат теста: не удалось
Продолжительность теста: 0:00:00.0572447Результат StackTrace:
в Microsoft.Practices.Unity.ResolvedArrayParameter..ctor(Тип arrayParameterType, Тип elementType, Object[] elementValues)
в Microsoft.Practices.Unity.ResolvedArrayParameter`1..ctor(Object[] elementValues)
в UnitTestProject11.UnitTest1.TestMethod1() в c: \ temp \ UnitTestProject11 \ UnitTestProject11 \ UnitTest1.cs: строка 13
Сообщение о результате:
Метод тестирования UnitTestProject11.UnitTest1.TestMethod1 вызвал исключение:
System.InvalidProgramException: Common Language Runtime обнаружил недопустимую программу.
Самая необычная особенность этой проблемы, очевидно, состоит в том, что подделки даже не должны появляться непосредственно в коде, чтобы не проявиться.
Обширный беспорядок показывает, что перенацеливание тестового проекта на.NET 4.5 "решает" проблему, которая не является для меня новой из-за другой проблемы, которую я опубликовал несколько недель назад.
Еще больше возиться с практически всеми фальшивыми настройками (контракты кода и т. Д.) Не дали решения.
Любой совет по этому вопросу будет очень признателен.
1 ответ
Единственное общее решение состоит в том, чтобы убедиться, что все части соответствуют версии CLR, которую вы используете очень близко, и что VS имеет последние обновления.
Для этой проблемы не существует волшебной пули. Вам нужно знать (выкопать) точную совместимость версий CLR всех частей, которые подключены в вашем проекте, когда вы вводите подделки. Имейте в виду, что "совместимость" может быть просто вопросом манифеста, но чаще всего они связаны с нюансами того, как был / будет создан окончательный код и для какой версии виртуальной машины.
Эти вещи обычно не имеют значения для запуска и отладки, так как есть несколько уровней, которые гарантируют, что незначительные различия версий либо не имеют значения, либо вы получаете молчаливое переключение на то, с чем ваш код объявлен совместимым.
Но когда вы используете Fakes, "система" внедряет необработанный код в ваш (который включает в себя сторонние библиотеки), и это означает, что он пропускает большинство проверок - иначе работать не могло. Но когда наступает время для фактического запуска кода, движок (виртуальная машина) должен выполнить некоторые проверки для своей собственной безопасности / целостности, и он имеет тенденцию становиться параноиком и выходить из-под контроля, если кажется, что объявления не совпадают достаточно близко.
Это причина, по которой кто-то спросил, являются ли соответствующие сборки строго названными или подписанными. Это единственный уровень гарантии, которому "система" действительно будет доверять. Без этого он будет в некоторой степени угадывать, и, в то время как для нормальных запусков это в основном не имеет значения, если для внедрения кода имеет большое значение
Я до сих пор не говорю о возможных реальных проблемах - все это при условии, что с реальным кодом все в порядке и просто объявления перепутаны. Вы можете попробовать поиграть с этим, но это займет много времени и усилий. Гораздо проще проверить, можно ли получить версии сборок, которые лучше соответствуют.
Тот факт, что ошибки исчезли, когда вы переключили свой вариант обратно на 4.5, говорит о том, что либо некоторые из задействованных сборок не "достаточно близки" для 4.6, либо могут быть некоторые проблемы с внедрением кода, которые были исправлены обновлениями, которые вы не приняли в еще.
Да, это связано с большим количеством боли, но это цена желания быть на границе.