我想要做的是实例化UserContext
(理想情况下每个用户一个实例)。 UserContext
取决于当前登录的用户。
MyUser
是通过调用GlobalContext.User(username)
从我的Startup.Configuration(IAppBuilder app)
:
private static IContainer RegisterServices()
{
var builder = new ContainerBuilder();
builder.RegisterApiControllers(System.Reflection.Assembly.GetAssembly(typeof(MyWeb.API.Startup)));
builder.RegisterType<GlobalContext>().As<IGlobalContext>().SingleInstance();
builder.Register(c => c.Resolve<IGlobalContext>().User(
HttpContext.Current.User.Identity.Name)
).As<MyUser>();
builder.RegisterType<UserContext>().As<IUserContext>().InstancePerLifetimeScope();
return builder.Build();
}
在IIS Express中运行时,一切似乎都能正常工作。
当我在使用Owin WebApp.Start<Startup>(url: BaseAddress)
HttpContext.Current
的集成测试中运行此操作时为空。这是我迄今为止所做的所有阅读的预期,但是替代方案是什么?
我想我需要访问owinContext或autofac生命周期范围才能在解析期间获取当前用户,但我该怎么做?
有更好的方法吗?或者我错过了一些微不足道的东西?
感谢所有帮助。
已编辑添加信息
如果它有帮助我在这里包括我的Configuration()
方法:
using System.Web;
using System.Web.Http;
using Autofac;
using Autofac.Integration.WebApi;
using Owin;
using System.Reflection;
namespace SomeNameSpace
{
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
var configuration = new HttpConfiguration{ IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always };
WebApiConfig.Register(configuration);
BreezeConfig.Register(configuration);
CorsConfig.Register(configuration);
// Autofac IoC
var container = RegisterServices();
app.UseAutofacMiddleware(container);
app.UseWindowsAuthentication();
var urt = new UserRolesTranformer(new GlobalContext());
app.UseClaimsTranformation(urt.Transformation);
app.UseAutofacWebApi(configuration);
configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);
//app.Use(typeof(TestMiddleware));
app.UseAutofacWebApi(configuration);
app.UseWebApi(configuration);
}
}
终极目标: 创建一个模拟多个并发用户登录的测试,并确保每个用户获得自己的UserContext实例。
答案 0 :(得分:2)
在单元测试的情况下,您不应该真正需要访问HttpContext或OwinContext。正如我想象你已经发现的那样,单元测试没有HttpContext的概念。
我假设您的IGlobalContext有一个方法User,它接受一个Username并返回一个User,可能是根据当前上下文传入的Username从您的数据库返回的?
您应该为您的网站和单元测试进行不同的Autofac注册,以便您可以在每个环境中拥有不同的依赖关系。然后在单元测试Autofac注册中,您可以注册一个完全不同的依赖项,以便在单元测试中解析,或者您可以传入您的User方法,一个您知道存在的模拟用户名。
因此,您可以将此作为您网站上的Autofac注册。
private static IContainer RegisterServices()
{
var builder = new ContainerBuilder();
builder.RegisterApiControllers(System.Reflection.Assembly.GetAssembly(typeof(MyWeb.API.Startup)));
builder.RegisterType<GlobalContext>().As<IGlobalContext>().SingleInstance();
builder.Register(c => c.Resolve<IGlobalContext>().User(
HttpContext.Current.User.Identity.Name)
).As<MyUser>();
builder.RegisterType<UserContext>().As<IUserContext>().InstancePerLifetimeScope();
return builder.Build();
}
然后在你的单元测试中,当你用这样的东西注册你的Autofac注册时。
private static IContainer RegisterServices()
{
var builder = new ContainerBuilder();
builder.RegisterApiControllers(System.Reflection.Assembly.GetAssembly(typeof(MyWeb.API.Startup)));
builder.RegisterType<GlobalContext>().As<IGlobalContext>().SingleInstance();
builder.Register(c => c.Resolve<IGlobalContext>().User(
"MyTestUser")
).As<MyUser>();
builder.RegisterType<UserContext>().As<IUserContext>().InstancePerLifetimeScope();
return builder.Build();
}
通过这种方式,您可以在单元测试中了解您传入的用户以及应该返回的用户。
或者使用像你这样完全嘲笑的用户......
public class TestUser : MyUser
{
//Known Test Scenario Properties and Methods as required
}
private static IContainer RegisterServices()
{
var builder = new ContainerBuilder();
builder.RegisterApiControllers(System.Reflection.Assembly.GetAssembly(typeof(MyWeb.API.Startup)));
builder.RegisterType<GlobalContext>().As<IGlobalContext>().SingleInstance();
builder.RegisterType<TestUser>().As<MyUser>();
builder.RegisterType<UserContext>().As<IUserContext>().InstancePerLifetimeScope();
return builder.Build();
}
我希望这有帮助吗?