2012-09-30 6 views
8

Po przeczytaniu wpisu "How to check if method has an attribute" Jestem krokiem do rozwiązania problemu, który nie pozwala mi zasnąć.Jak sprawdzić, czy metoda ma atrybut (z interfejsami, rzutowaniem i streszczeniem)?

przedstawię sytuację:

(pracuję z ASP.Net MVC 4)

tych interfejsów:

public interface IFlyable 
{ 
    ActionResult Fly(); 
}  

public interface IRunnable 
{ 
    ActionResult Run(); 
} 

Ta klasa abstrakcyjna:

public abstract class SuperHero : Controller 
{ 
    public void SavePeople() 
    { 
    }  
} 

Regulator:

public class SuperManController : SuperHero,IFlyable,IRunnable { 

    [Authorize] 
    public ActionResult Fly(){ 
     // Flying... 
    }  

    [Authorize] 
    public ActionResult Run(){ 
     // Running... 
    }  

} 

Ta klasa abstrakcyjna (do testów)

[TestClass] 
public abstract class SuperHeroTest<TSuperHero>{ 

    protected abstract TSuperHero GetSuperHero(); 

    [TestMethod] 
    public void IfSuperHeroCanFlyMustHaveAuthorizeAttribute(){ 

     var superHero=GetSuperHero(); 

     if(superHero is IFlyable) 
     { 
      var superHeroFlyable = (IFlyable) superHero; 

      var have = MethodHasAuthorizeAttribute(() => superHeroFlyable.Fly()); 

      Assert.IsTrue(have); 
     } 

    } 
} 

I wreszcie ta klasa odziedziczona SuperHeroTest przetestować SuperManController:

[TestClass] 
public class SuperManControllerTest : SuperHeroTest<SuperManController>{ 

    private SuperManController _superManController; 

    public SuperManControllerTest(){ 
     _superManController=new SuperManController(); 
    } 


    protected override SuperManController GetSuperHero() 
    { 
     return _superManController; 
    } 

} 

Metoda MethodHasAuthorizeAttribute jest: (z postu powyżej)

public static MethodInfo MethodOf(Expression<System.Action> expression) 
{ 
    MethodCallExpression body = (MethodCallExpression)expression.Body; 
    return body.Method; 
} 

public static bool MethodHasAuthorizeAttribute(Expression<System.Action> expression) 
{ 
    var method = MethodOf(expression); 

    const bool includeInherited = false; 
    return method.GetCustomAttributes(typeof(AuthorizeAttribute),includeInherited).Any(); 
} 

Mój problem jest:

Wezwanie MethodHasAuthorizeAttribute(() => superHeroFlyable.Fly()) w SuperHeroTest klasa powrót false kiedy powinien on powrócić true.

(Zastosowana metoda Fly w klasie SuperManController ma atrybut Authorize).

Dodałem atrybut Authorize w metodzie Fly do IFlyable, a następnie wrócimy true.

public interface IFlyable 
{ 
    [Authorize] 
    ActionResult Fly(); 
} 

Jak mogę zrobić, aby dokonać implementacji zamiast interfejsu?

+0

Dzięki Dove do edycji! –

Odpowiedz

9

Po wprowadzeniu pewnych modyfikacji w metodzie IfSuperHeroCanFlyMustHaveAuthorizeAttribute() można ją uruchomić.

Najpierw sprawdź, czy kontroler implementuje interfejs IFlyable. Jeśli tak, pobierz MethodInfo dla metody Fly kontrolera. Następnie wystarczy sprawdzić atrybuty zwróconej metody MethodInfo. W ten sposób sprawdzasz, czy implementacja ma atrybut zamiast interfejsu.

Poniższe działa OK:

[TestClass] 
public abstract class SuperHeroTest<TSuperHero> 
{ 
    protected abstract TSuperHero GetSuperHero(); 

    [TestMethod] 
    public void IfSuperHeroCanFlyMustHaveAuthorizeAttribute() 
    { 
     var superHero = GetSuperHero(); 

     if (superHero is IFlyable) 
     { 
      var superHeroFlyable = superHero; 
      var method = typeof (TSuperHero).GetMethod("Fly"); 
      var hasAttribute = 
       method.GetCustomAttributes(typeof (AuthorizeAttribute), false).Any(); 
      Assert.IsTrue(hasAttribute); 
     } 
    } 

    public static MethodInfo MethodOf(Expression<System.Action> expression) 
    { 
     var body = (MethodCallExpression)expression.Body; 
     return body.Method; 
    } 

    public static bool MethodHasAuthorizeAttribute(Expression<System.Action> expression) 
    { 
     var method = MethodOf(expression); 
     const bool includeInherited = false; 
     return method.GetCustomAttributes(
      typeof(AuthorizeAttribute), includeInherited).Any(); 
    } 
} 
+0

Działa doskonale! Christophe dziękuję bardzo! –

+0

Test przechodzi, jeśli superHero nie jest IFable, asercja powinna znajdować się poza blokiem if – Grokodile

Powiązane problemy