Использование CSLAs WCF при запуске тестов XUnit в обозревателе тестов вызывает исключение олицетворения

Мы используем XUnit 2.1.0 от NuGet с соответствующими исполнителями, консолью и visualstudio, как описано в документации здесь под заголовком "Выполнение тестов с Visual Studio" и соответствующим содержанием.

Я также использую Visual Studio 2015 Enterprise Update 2. Единственное, что достаточно устарело, это CSLA, мы на 4.0.1 (думаю, 5 лет?)

Когда мы запускаем любые тесты, требующие выборки DataPortal, тест падает, как только выборка DataPortal пытается быть отправлена ​​на сервер. WCF выдает «System.ServiceModel.FaultException», в котором говорится: «Недопустимый токен для олицетворения — его нельзя дублировать». Важно отметить, что ни один из тестов не пытается выдать себя за другого пользователя. падение происходит в любом тесте, который пытается использовать CSLA для вызова DataPortal. Недавно мы перешли с xunit 1.x на 2.x через nuget, раньше мы запускали xunit из xunit runner при локальном тестировании наших тестов, но теперь это устарело. Все тесты прошли абсолютно нормально как через графический интерфейс, так и через консоль для xunit 1.x. Теперь мы должны использовать Visual Studio Runner с xunit 2.x, мы получаем это сумасшедшее исключение.

редактировать: если вы запускаете консольный бегун xunit 2.x из-за пределов визуальной студии, тесты также в порядке на 2.x, это часть визуальной студии, которая не работает.

Трассировка стека ниже:

Server stack trace: 
   at System.ServiceModel.Channels.ServiceChannel.ThrowIfFaultUnderstood(Message reply, MessageFault fault, String action, MessageVersion version, FaultConverter faultConverter)
   at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]: 
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at Csla.Server.Hosts.IWcfPortal.Fetch(FetchRequest request)
   at Csla.DataPortalClient.WcfProxy.Fetch(Type objectType, Object criteria, DataPortalContext context) in D:\Dev\Insight\Trunk\Source\Lib\CSLA .NET\4.0\Source\Csla\DataPortalClient\WcfProxy.cs:line 162
   at Csla.DataPortal.Fetch(Type objectType, Object criteria) in D:\Dev\Insight\Trunk\Source\Lib\CSLA .NET\4.0\Source\Csla\DataPortal.cs:line 245
   at Csla.DataPortal.Fetch[T](Object criteria) in D:\Dev\Insight\Trunk\Source\Lib\CSLA .NET\4.0\Source\Csla\DataPortal.cs:line 170

Опять же, это отлично работает, если мы запускаем тесты из другого средства запуска тестов, например, старого средства запуска тестов xunit или CruiseControl.Net (мы используем CC.Net для непрерывной интеграции, и это отлично запускает тесты)


person Skintkingle    schedule 01.08.2016    source источник


Ответы (1)


Я думаю, что это больше связано с тем, как средство запуска тестов Visual Studio настраивает текущего участника-пользователя. Большинство других тестовых исполнителей, по-видимому, используют пустой GenericPrincipal, тогда как VS, по-видимому, устанавливает текущий принципал в олицетворенную версию текущего идентификатора Windows. Это означает, что вы получаете ошибку, которую видите, когда CSLA.NET снова пытается олицетворять ее.

Эта проблема подробно обсуждается в этой записи блога, касающейся NUnit: http://www.ienumerable.it/2015/03/21/Setting-up-good-fixture.html

Относительно простой способ решить эту проблему с помощью xUnit (адаптированный из приведенного выше блога) — настроить атрибут BeforeAfterTestAttribute, чтобы задать для него значение GenericPrincipal перед запуском теста, а затем восстановить исходный участник после этого. Это гарантирует, что он будет работать с одним и тем же принципалом, независимо от используемого средства запуска тестов.

public class RequiresGenericPrincipalAttribute : BeforeAfterTestAttribute
{
    private IPrincipal _originalPrincipal;
    public override void Before(MethodInfo methodUnderTest)
    {
        _originalPrincipal = System.Threading.Thread.CurrentPrincipal;
        System.Threading.Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity(""), new String[] { });
        base.Before(methodUnderTest);                        
    }

    public override void After(MethodInfo methodUnderTest)
    {
        base.After(methodUnderTest);
        System.Threading.Thread.CurrentPrincipal = _originalPrincipal;
    }

}
person Grinden    schedule 01.08.2016
comment
Интересно, что на данный момент у нас есть около 1200 модульных тестов. Добавить атрибут ко всем из них будет сложно. это единственный способ заставить его работать в Visual Studio? Добавляете этот атрибут во все наши тесты? Нет ли способа помешать Visual Studio олицетворять себя? - person Skintkingle; 01.08.2016
comment
Извините, я не знаю, как изменить пользователя, которого использует средство запуска тестов VS. Использует ли какой-либо из ваших тестов атрибут BeforeAfterTestAttribute, который может просто расширить этот? Может сделать вещи немного быстрее. - person Grinden; 01.08.2016
comment
Или найти и заменить: [Факт] -> [Факт, RequiresGenericPrincipal]? - person Grinden; 01.08.2016
comment
Мы поместили атрибут во все тесты, и на самом деле это все еще происходит. Похоже, что это происходит во всех тестах, которые сейчас пытаются изменить участника безопасности в тесте (но все еще происходит до того, как тест фактически начнется), есть идеи? - person Skintkingle; 08.08.2016