我正在尝试设置一些单元测试,以确保URL将根据路由表映射到适当的控制器和操作,并且目标操作方法和控制器存在于相关程序集中。
我遇到的唯一问题是测试是否存在一个动作方法,其中已应用ActionNameAttribute
来启用以破折号分隔的动作名称映射,例如,“联系我们”表单网址: /contact-us
映射到Forms控制器上的ContactUs方法,因为ContactUs方法签名是这样定义的:
[ActionName("contact-us")]
public ActionResult ContactUs()
我已经设置了以下方法,我在每个测试中运行,并适用于所有使用ActionNameAttribute
重新定义的操作方法名称的情况:
private static bool ActionIsDefinedOnController(string expectedActionName, string controllerName, string assemblyName)
{
var thisControllerType = Type.GetType(AssemblyQualifiedName(controllerName, assemblyName), false, true);
if (thisControllerType == null)
return false;
var allThisControllersActions = thisControllerType.GetMethods().Select(m => m.Name.ToLower());
if( allThisControllersActions.Contains(expectedActionName.ToLower()))
return true;
var methods = thisControllerType.GetMethods();
//If we've so far failed to find the method, look for methods with ActionName attributes, and check in those values:
foreach (var method in methods)
{
if (Attribute.IsDefined(method, typeof(ActionNameAttribute))
{
var a = (ActionNameAttribute) Attribute.GetCustomAttribute(method, typeof (ActionNameAttribute));
if (a.Name == expectedActionName)
return true;
}
}
return false;
}
...但是只要使用ActionNameAttribute
重新定义方法的名称,检查Attribute.IsDefined(method, typeof(ActionNameAttribute)
就会失败(返回false
),即使我可以在自定义列表中看到该属性-attributes在我的调试会话中:
为什么这次检查失败,何时应该通过?
我已经能够构建一个不同的支票:
更新我最初在这里粘贴了错误的代码,这是修改后的内容:
List<string> customAttributes = method.GetCustomAttributes(false).Select(a => a.ToString()).ToList();
if (customAttributes.Contains("System.Web.Mvc.ActionNameAttribute"))
{
var a = (ActionNameAttribute) Attribute.GetCustomAttribute(method, typeof (ActionNameAttribute));
if (a.Name == expectedActionName)
return true;
}
...现在我的条件是抓住应用ActionNameAttribute
的情况,但现在Attribute.GetCustomAttribute()
返回null。所以我无法检查动作名称的值以与预期值进行比较... arrrrgh!
答案 0 :(得分:2)
我只想:
//If we've so far failed to find the method, look for methods with ActionName attributes, and check in those values:
foreach (var method in methods)
{
var attr = method.GetCustomAttribute<System.Web.Mvc.ActionNameAttribute>();
if (attr!=null && attr.Name == expectedActionName)
{
return true;
}
}
正如我在评论中所说,我怀疑您在ActionNameAttribute
来电中接听错误的 typeof
,所以我一直都是明确的