2011-01-04 8 views
4

Ich habe mvc Anwendung und ich arbeite mit poco Objekte und Schreibgerät Test. Problem ist, dass alle meine Tests fehlschlagen, wenn sie diese Codezeile erreichen. Roles.IsUserInRole ("someUser", "role"). Soll ich eine neue Schnittstelle oder ein Repository für Rollen oder ... implementieren? ThxUnit Test (mvc) -Problem mit Rollen

+1

Es gibt nicht genug Informationen hier, um Ihre Frage zu beantworten. Bitte überlege, Code zu überarbeiten/hinzuzufügen/Details zu deiner Frage hinzuzufügen. – Kendrick

+0

Warum scheitern sie? Können Sie Details der Ausnahme und des verwendeten Frameworks posten? In den meisten Frameworks werden Ausnahmetypen verwendet, die fehlschlagen. Daher kann es sich um einen Fehler oder eine Ausnahme handeln, die durch die Isolation für den Test verursacht wird. – StuperUser

+0

Ich habe Rolltests im Controller ähnlich wie [Unit-Testing-Security-Model-Clickonce] (http://stackoverflow.com/questions/4585174/unit-testing-security-model-clickonce/4585686#4585686) – k3b

Antwort

10

Ich hatte das gleiche Problem beim Versuch, die Roles.IsUserInRole-Funktionalität in meinen codierten Unit-Tests zu verspotten. Meine Lösung war, eine neue Klasse namens Roleprovider und eine Schnittstelle mit der Methode IsUserInRole zu erstellen, die dann die System.Web.Security.Roles.IsUserInRole genannt:

public class RoleProvider: IRoleProvider 
{ 
    public bool IsUserInRole(IPrincipal userPrincipal) 
    { 
     return System.Web.Security.Roles.IsUserInRole(userPrincipal.Identity.Name, "User"); 
    } 
} 

Dann in meinem Code nenne ich die Roleprovider IsUserInRole Methode. Wie Sie eine Schnittstelle können Sie die IRoleProvider in Ihren Tests dann verspotten, hier gezeigten Beispiel wird unter Verwendung von Rhino Mocks:

var roleProvider = MockRepository.GenerateStub<IRoleProvider>(); 
roleProvider.Expect(rp => rp.IsUserInRole(userPrincipal)).Return(true); 

Hoffnung, das hilft.

+0

Thx, das funktioniert für mich (: – Cipiripi

+0

Dies ist sehr gut für die Testbarkeit. Ein bisschen ärgerlich, dass meine Controller jetzt eine Instanz von RoleProvider benötigen. Kann am Ende eine Basis-Controller-Klasse erstellen, die dies eingebaut hat (zusammen mit einigen anderen gängigen Eigenschaften/Felder). Danke für den Vorschlag! – Killnine

0

Sie einen leichten Wrapper mit einem Prädikat/Func erstellen.

public static Predicate<string> IsUserInRole = role => Roles.IsUserInRole(role); 

Dann nutzen IsUserInRole() anstelle von Roles.IsUserInRole(). Zur Laufzeit erhalten Sie das gleiche Verhalten. Aber bei Testzeit können Sie die Funktion außer Kraft setzen, so dass sie nicht die Roleprovider zugreift

MyClass.IsUserInRole = role => true; 

Wenn Sie es vorziehen, nicht eine öffentliche statische haben Sie die Prädikats über Ihren Konstruktor injizieren könnte und speichern Sie es als Privat nur lesbar.

class MyClass 
{  
    private readonly Predicate<string> IsUserInRole; 
    MyClass(Predicate<string> roleChecker) { this.IsUserInRole = roleChecker } 
    MyClass() : this(role => Roles.IsUserInRole(role)) { } 
} 

Wenn Sie Moq verwenden, können Sie ein Mock zurückkehren und steuern dann den Rückgabewert und/oder überprüfen Sie die Methode aufgerufen wurde. Und prüfen Sie, welcher Parameterwert an das Prädikat gesendet wurde.

Mock<Predicate<string>> mockRoleChecker = new Mock<Predicate<string>>(); 
var cut = new MyClass(mockRoleChecker.Object); 
var expectedRole = "Admin"; 
mockRoleChecker.SetReturnsDefault<bool>(true); // if not specified will return false which is default(bool) 

cut.MyMethod(); 

mockRoleChecker.Verify(x => x(expectedRole), Times.Once());