28

Я использую Visual Studio 2015 Enterprise RTM для написания модульных тестов для проекта, который использует Unity Container.Visual Studio 2015 InvalidProgramException в модульном тестировании с подделками

Я обнаружил, что простой акт добавления сборки подделок для единства, даже не на самом деле с помощью подделку, достаточно, чтобы произвести это исключение:

System.InvalidProgramException: Common Language Runtime обнаружена неверная программа.



Рассмотрим следующие шаги для воспроизведения:

  • Использование Visual Studio 2015 Enterprise RTM создать Unit Test проект таргетирования .NET 4.6

  • Добавьте пакет NuGet "Единство" версия 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 ссылки и выберите " Add Fakes Assembly "

  • Заново запустить тест

  • Observe следующего замечательный провал теста:

Тест Имя: TestMethod1
Тест FullName: UnitTestProject11.UnitTest1.TestMethod1
Test Источник: C: \ TEMP \ UnitTestProject11 \ UnitTestProject11 \ UnitTest1.cs: линия 12
Тест Результат: Failed
Test Продолжительность: 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
Результат Сообщение:
метод Test UnitTestProject11.UnitTest1.TestMethod1 бросил исключение:
системы. InvalidProgramException: Common Language Runtime обнаружил недопустимую программу.



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

Огромное количество пустяков показывает, что перенацеливание тестового проекта на .NET 4.5 «исправляет» проблему, которая для меня является не стартером из-за ошибки another. Я опубликовал несколько недель назад.

Еще более возиться с практически всеми настройками подделок (кодовые контракты и т. Д.) Не давало решения.

Любой совет по этому вопросу будет очень признателен.

+0

Начал щедрость, потому что мы сталкиваемся с тем же 'InvalidProgramException', когда мы используем' ShimLocalPrintServer.Constructor ...' для проверки метода, который создает экземпляр 'System.Printing.LocalPrintServer'. «UnityContainer» не требуется для воспроизведения этой ошибки. И сброс фреймворка не помог. Исключение возникает, когда тестируемый метод вызывает 'new LocalPrintServer (новая строка [0], PrintSystemDesiredAccess.EnumerateServer);' –

+0

Вы видели этот похожий вопрос? Http: // StackOverflow.com/questions/14578355/system-invalidprogramexception-when-executing-unit-tests-in-mstest-after-microso – BlakeH

+0

Почему вы еще не установили Visual Studio Update 1? – CSharpie

ответ

2

Единственное общее решение - убедиться, что все части соответствуют версии CLR, которую вы используете очень близко, и что VS имеет последние обновления.

Для этой проблемы нет волшебной пули. Вам необходимо знать (выкапывать) точную совместимость версий CLR всех частей, которые подключены в вашем проекте, когда вы вводите подделки. Имейте в виду, что «совместимость» может быть только вопросом манифеста, но чаще всего это вопрос нюансов о том, как был/был создан окончательный код и для какой версии виртуальной машины.

Эти вещи, как правило, не имеют значения для запуска и отладки, поскольку есть несколько уровней, которые гарантируют, что незначительные различия версий либо не имеют значения, либо вы получаете бесшумный переключатель, независимо от того, как объявлен ваш код.

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

Это причина, по которой кто-то спросил, связаны ли сборные по имени или подписке. Это единственный уровень гарантии, которому «система» действительно будет доверять. Без этого он будет делать угадывание, и в большинстве случаев это не имеет значения для обычных прогонов, если дело касается ввода кода.

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

Тот факт, что ошибки исчезли, когда вы включили свой аромат обратно в 4.5, говорит вам, что либо некоторые из задействованных сборок не являются «достаточно близкими» для 4.6, либо могут быть некоторые сбои с введением кода, которые были исправлены обновлениями, Еще не принято.

Да, это связано с большой болью, но это цена желающих быть на границе.