自定义SynchronizationContext在unittest中异步设置Thread.CurrentPrincipal

时间:2015-09-26 12:27:26

标签: c# unit-testing asynchronous async-await

此问题与Set Thread.CurrentPrincipal Asynchronously?类似。但是,在我的情况下,我试图在单元测试中使用它,并希望使用自定义的SynchronizationContext来解决这个问题。

是否有一个SynchronizationContext,其行为类似于ASP.NET使用的,但单元测试可以使用它? (我的代码在ASP.NET中运行得非常好。)

特别是,它是AspNetSynchronizationContext的一个特性,它使主体能够“摆脱”我想要的异步方法。

当在asp.net应用程序/上下文中调用SetCurrentPrincipalAsync(bellow)方法时,调用方法不会覆盖Thread.CurrentPrincipal。 - 但是当测试运行时,它将失败。

[Fact]
public async Task SetSynchronizationContext()
{
    //SynchronizationContext.SetSynchronizationContext(new SomeCustomSynchronizationContext());
    await SetCurrentPrincipalAsync();
    Assert.Equal("Name", Thread.CurrentPrincipal.Identity.Name);
}

static async Task SetCurrentPrincipalAsync()
{
    var principal = new GenericPrincipal(new GenericIdentity("Name"), new []{"Role"});
    Thread.CurrentPrincipal = principal;
    if (HttpContext.Current != null)
        HttpContext.Current.User = principal;
    await Task.Delay(TimeSpan.FromSeconds(1));
}

1 个答案:

答案 0 :(得分:1)

检查是否

等待SetCurrentPrincipalAsync();

线程未更改,因为如果在等待执行后SynchronizationContext.Current == null(并且默认情况下其等于null,除了UI线程等)将继续在任何可用的线程池线程中。 另一个建议,改变所有系统类,如HttpContext,使用模拟对象,测试代码而不是系统;)