0

我正在尝试设置一些单元测试,以确保 URL 将根据路由表映射到适当的控制器和操作,并且目标操作方法和控制器存在于相关程序集中。

我遇到的唯一剩下的问题是测试一个动作方法的存在,其中 anActionNameAttribute已应用于启用破折号分隔的动作名称映射,例如,“联系我们”表单 url:/contact-us映射到表单上的 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),即使我可以在调试会话中的自定义属性列表中看到该属性:

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!

4

1 回答 1

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;
    }
}

正如我在评论中所说,我怀疑您在通话中接 ActionNameAttributetypeof电话,所以我一直很明确

于 2013-06-07T13:28:00.320 回答