Attribute.IsDefined返回false,Attribute.GetCustomAttribute为定义的ActionNameAttribute返回null

时间:2013-06-07 12:43:28

标签: asp.net-mvc unit-testing

我正在尝试设置一些单元测试,以确保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在我的调试会话中:

Failure of Action.IsDefined

为什么这次检查失败,何时应该通过?

我已经能够构建一个不同的支票:

更新我最初在这里粘贴了错误的代码,这是修改后的内容:

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!

1 个答案:

答案 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,所以我一直都是明确的