我正在尝试对涉及的城堡windsor进行一些测试,在我的一个测试中,我想检查windsor安装程序,所以我检查容器是否可以解析我的组件给定其界面。
到目前为止,非常好,问题在组件在其安装程序中具有PerWebRequest生活方式时开始,首先它抱怨HttpContext.Current为null,有一个解决了在测试设置中创建假上下文我现在有这个nunit测试中的例外
System.Exception:看起来你忘了注册http模块Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule 将''添加到web.config上的部分。如果您在集成模式下运行IIS7,则需要将其添加到
下的部分当我从NUnit运行时,如何在windsor中注册模块或类,以便它可以工作,或者如何模拟,因为在此测试中并不是真正的Web请求,只需检查容器是否解决了类型。
如果我在真正的webrequest之外对这个组件进行任何集成测试,也会发生同样的事情,有没有办法使这个工作或真的模拟一个Web请求,以便可以运行这些测试?
提前交易
费尔
答案 0 :(得分:17)
在测试中,您可以订阅ComponentModelCreated事件,并将每个Web请求组件的生活方式更改为其他内容。 (example)。
如果您正在编写具有单个请求范围的集成测试,则单例应该这样做。
如果您正在编写跨越多个请求的集成测试,则可以使用contextual lifestyle来模拟请求的范围。
编辑:包括示例中的代码(不再可用):
container.Kernel.ComponentModelCreated += Kernel_ComponentModelCreated;
...
void Kernel_ComponentModelCreated(Castle.Core.ComponentModel model)
{
if (model.LifestyleType == LifestyleType.Undefined)
model.LifestyleType = LifestyleType.Transient;
}
答案 1 :(得分:0)
如果您还想检查范围类型是否是针对每个Web请求的,您也可以这样做
var isPerWebRequestScope = JsonConvert.SerializeObject(model.ExtendedProperties).Contains("Castle.Facilities.AspNet.SystemWeb.WebRequestScopeAccessor")
答案 2 :(得分:0)
从Windsor的第5版开始,如果您使用的是Castle.Facilities.AspNet.SystemWeb.WebRequestScopeAccessor
,那么可接受的答案将不起作用,因为PerWebRequest生活方式已经成为范围内的生活方式。
我通过将ComponentModelCreated
委托更改为以下内容来使其工作:
void Kernel_ComponentModelCreated(Castle.Core.ComponentModel model)
{
const string CastleScopeAccessorType = "castle.scope-accessor-type";
if (model.ExtendedProperties.Contains(CastleScopeAccessorType))
{
model.ExtendedProperties.Remove(CastleScopeAccessorType);
}
}
答案 3 :(得分:0)
我最终实现了此扩展。 ATTN :必须在加载具有 PerWebRequest 生活方式的组件之前调用:
public static class WindsorContainerExtensions
{
public static IWindsorContainer OverridePerWebRequestLifestyle(this IWindsorContainer container)
{
container.Kernel.ComponentModelCreated += model =>
{
if (model.IsPerWebRequestLifestyle())
{
model.LifestyleType = LifestyleType.Transient;
}
};
return container;
}
private static bool IsPerWebRequestLifestyle(this ComponentModel model)
{
return model.LifestyleType == LifestyleType.Scoped
&& model.HasAccessorType(typeof(WebRequestScopeAccessor));
}
private static bool HasAccessorType(this ComponentModel model, Type type)
=> model.HasExtendedProperty("castle.scope-accessor-type", type);
private static bool HasExtendedProperty<T>(this ComponentModel model, object key, T expected)
{
return model.ExtendedProperties[key] is T actual
&& EqualityComparer<T>.Default.Equals(actual, expected);
}
}
需要这些导入:
using System;
using System.Collections.Generic;
using Castle.Core;
using Castle.Facilities.AspNet.SystemWeb;
using Castle.Windsor;