我有一个使用 ServiceStack Ormlite 的现有 MCV 应用程序。我正在添加一些控制器测试,并且可以毫无问题地模拟注入的类,但是我们在使用 ServiceStack AuthUserSession 时遇到问题,某些控制器使用该会话来检查会话的权限和其他属性。
所有控制器都继承自基本控制器
_Controller
,它具有以下属性:
public MyAuthUserSession AuthUserSession => SessionAs<MyAuthUserSession>();
MyAuthUserSession
扩展了 AuthUserSession
类并具有一些额外的方法和数据成员。
在控制器中,我们使用此属性来检查特定情况的权限:
model.CanEdit = AuthUserSession.HasEntityPermission(PermissionType.Update, PermissionEntity.MyEntity);
但是,当作为单元测试运行时,调用
AuthUserSession
总是会抛出空引用异常。
我尝试通过包含测试 AppHost 来填充会话:
public class TestAppHost : AppHostBase
{
public TestAppHost() : base("Test Service", typeof(LocationsService).Assembly) { }
public override void Configure(Container container)
{
Plugins.Add(new AuthFeature(() => new MyAuthUserSession(), new IAuthProvider[] { new BasicAuthProvider() })
{
IncludeAssignRoleServices = false,
IncludeAuthMetadataProvider = false,
IncludeRegistrationService = false,
GenerateNewSessionCookiesOnAuthentication = false,
DeleteSessionCookiesOnLogout = true,
AllowGetAuthenticateRequests = req => true
});
}
}
它采用与主应用程序相同的参数,但是 AuthUserSession 永远不会被填充。我尝试过手动设置:
var authService = appHost.Container.Resolve<AuthenticateService>();
var session = new MyAuthUserSession();
authService.SaveSessionAsync(session).Wait();
手动设置会话不起作用 - 我怀疑保存的会话与控制器的
SessionAs<MyAuthUserSession>()
没有关联。
这开始看起来更接近集成测试而不是单元测试,但本质上我只需要基本控制器上的
AuthUserSession
属性即可通过手动设置或模拟它来返回用于测试的会话。由于这是一个遗留应用程序,更改控制器上的 AuthUserSession
属性是不切实际的(可能有 1000 个引用,因此更改它需要大量的重构)。由于它是常规属性,我无法用 NSubstitute 替换响应(例如。MyController.AuthUserSession.Returns(new MyAuthUserSession()
)
是否有任何方法可以设置或替换 Servicestack 中的
SessionAs<MyAuthUserSession>()
方法或控制器上的 AuthUserSession
属性?
首先查看 ServiceStack 测试文档,了解如何使用
BasicAppHost
创建一个测试 AppHost,该 AppHost 配置了 Config.TestMode=true
,允许您在 IOC 中注册您的会话:
container.Register<IAuthSession>(new MyAuthUserSession());
或者,您可以通过在
IRequest.Items
字典中设置请求来填充会话,例如:
service.Request ??= new BasicRequest();
service.Request.Items[Keywords.Session] = new MyAuthUserSession();