【问题标题】:CSLAs WCF usage when running XUnit tests in vs test explorer causes an Impersonation Exception在 vs 测试资源管理器中运行 XUnit 测试时 CSLA 的 WCF 使用会导致模拟异常
【发布时间】:2016-08-01 11:59:38
【问题描述】:

我们正在使用来自 NuGet 的 XUnit 2.1.0 以及相关的运行程序、控制台和 visualstudio,如“使用 Visual Studio 运行测试”标题和相关内容下记录的 here

我也在使用 Visual Studio 2015 Enterprise Update 2。 唯一合理过时的是 CSLA,我们在 4.0.1 上(我认为 5 岁?)

当我们运行任何需要 DataPortal 提取的测试时,一旦 DataPortal 提取尝试发送到服务器,测试就会失败。 WCF 引发“System.ServiceModel.FaultException”,说明“用于模拟的令牌无效 - 它不能被复制。”重要的是要注意没有任何测试试图冒充另一个用户。跌倒发生在任何尝试使用 CSLA 进行 DataPortal 调用的测试中。 我们最近通过 nuget 从 xunit 1.x 迁移到 2.x,我们曾经在本地测试测试时从 xunit 运行器运行 xunit,但现在已弃用。通过 xunit 1.x 的 Gui 和控制台运行程序,这些测试都运行得非常好。现在我们必须在 xunit 2.x 中使用 Visual Studio 运行程序,我们遇到了这个疯狂的异常。

编辑:如果您从 Visual Studio 外部运行 xunit 2.x 控制台运行程序,则测试在 2.x 上也很好,这是无法正常工作的 Visual Studio 方面。

下面的堆栈跟踪:

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 进行持续集成,这可以正常运行测试)

【问题讨论】:

    标签: c# wcf visual-studio-2015 xunit csla


    【解决方案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;
        }
    
    }
    

    【讨论】:

    • 有趣的是,我们目前有大约 1200 个单元测试。为所有单元测试添加一个属性将是艰巨的。这是让它在 Visual Studio 中工作的唯一方法吗?将此属性添加到我们所有的测试中?有没有办法阻止 Visual Studio 模仿?
    • 抱歉,我不知道如何更改 VS 测试运行程序使用的用户。您的任何测试是否已经使用了可以扩展这个的 BeforeAfterTestAttribute?可能会让事情变得更快。
    • 或者查找并替换:“[Fact]” -> “[Fact, RequiresGenericPrincipal]”?
    • 我们已经在所有测试中添加了一个属性,它实际上仍在发生,看起来它现在正在尝试更改测试中的安全主体的任何测试(但实际上仍然发生在测试之前开始)有什么想法吗?
    猜你喜欢
    • 1970-01-01
    • 2014-06-15
    • 2020-05-13
    • 1970-01-01
    • 2022-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多