Unit Test (MVC) -Problem mit Rollen
-
15-10-2019 - |
Frage
Ich habe eine MVC -Anwendung und arbeite mit POCO -Objekten und schriftlicher Einheitstest. Das Problem ist, dass mein Test nicht fehlschlägt, wenn sie diese Zeile von Coderollen erreichen. Sollte ich eine neue Schnittstelle oder Repository für Rollen implementieren oder ...? Danke
Lösung
Ich hatte das gleiche Problem, als ich versuchte, die Rollen zu verspotten. Isuserinrol -Funktionalität in meinen codierten Unit -Tests. Meine Lösung bestand darin, eine neue Klasse namens RoleProvider und eine Schnittstelle mit Methode Isuserinrole zu erstellen, die dann das System nannte.
public class RoleProvider: IRoleProvider
{
public bool IsUserInRole(IPrincipal userPrincipal)
{
return System.Web.Security.Roles.IsUserInRole(userPrincipal.Identity.Name, "User");
}
}
Dann nenne ich in meinem Code die RoleProvider Isuserinrole -Methode. Wenn Sie eine Schnittstelle haben, können Sie den IroleProvider in Ihren Tests verspotten. Beispielsweise wird hier die Rhino -Mocks verwendet:
var roleProvider = MockRepository.GenerateStub<IRoleProvider>();
roleProvider.Expect(rp => rp.IsUserInRole(userPrincipal)).Return(true);
Hoffe das hilft.
Andere Tipps
Sie können eine benutzerdefinierte Methode einrichten, um Rollen zu überprüfen, die sich in Tests unterschiedlich verhalten, aber ich bevorzuge die Tests, einen Kontext einrichten, der mit den Standardmethoden funktioniert.
Sie können einen leichten Wrapper mit einem Prädikat/einem Func erstellen.
public static Predicate<string> IsUserInRole = role => Roles.IsUserInRole(role);
Verwenden Sie dann Isuserinrole () anstelle von Rollen.IsuserinRole (). In der Laufzeit erhalten Sie das gleiche Verhalten. Zum Testzeit können Sie die Funktion jedoch überschreiben, damit sie nicht auf den RoleProvider zugreifen
MyClass.IsUserInRole = role => true;
Wenn Sie es vorziehen, keine öffentliche Statik zu haben, können Sie das Prädikat über Ihren Konstruktor injizieren und als private Readonly speichern.
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ückgeben und dann den Rückgabewert steuern und/oder die aufgerufene Methode überprüfen. Und überprü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());