2009-07-27 4 views
1

Ich habe einen benutzerdefinierten RoleProvider (Standard-Webforms, keine MVC) erstellt und ich möchte es testen. Der Provider selbst integriert sich in eine benutzerdefinierte Implementierung von IIdentity (mit einigen hinzugefügten Eigenschaften).Moq benutzerdefinierte IIdentität

Ich habe dies im Moment:

var user = new Mock<IPrincipal>(); 
var identity = new Mock<CustomIdentity>(); 

user.Setup(ctx => ctx.Identity).Returns(identity.Object); 
identity.SetupGet(id => id.IsAuthenticated).Returns(true); 
identity.SetupGet(id => id.LoginName).Returns("test"); 

// IsAuthenticated is the implementation of the IIdentity interface and LoginName 

Jedoch, wenn ich diesen Test in VS2008 laufen dann bekomme ich folgende Fehlermeldung:

Ungültige Setup auf einem Nicht-overridable Mitglied: id => id.IsAuthenticated

Warum passiert das? Und am wichtigsten, was muss ich tun, um es zu lösen?

Grz, Kris.

Antwort

3

Sie sollten IIdentity (anstelle von CustomIdentity - nur möglich, wenn die Variablen, die Sie verspotten, in der Schnittstelle deklariert sind) vortäuschen oder die verwendeten Variablen als virtuell deklarieren.


So markieren Sie diese als virtuelle, tun: In Ihrem konkreten Klasse CustomIdentity verwenden

public virtual bool isAuthenticated { get; set; } 

statt

public bool isAuthenticated { get; set; } 

Moq und anderen Frameworks frei spöttischen nicht Lassen Sie sich Mitglieder und Methoden von konkreten Klassentypen vortäuschen, sofern sie nicht als virtuell markiert sind.

Schließlich könnten Sie den Mock selbst manuell erstellen. Sie können CustomIdentity zu einer Testklasse erben, die die Werte wie gewünscht zurückgibt. So etwas wie:

Diese Klasse würde nur in Tests verwendet werden, als eine Kopie für Ihre CustomIdentity.

--edit

Antwort in den Kommentaren zu hinterfragen.

+0

Was meinst du mit den verwendeten Variablen als virtuals deklarieren? Du meinst in meinem Test selbst? – XIII

+0

@XIII zusätzliche Erklärung hinzugefügt.Es sollte in Ihrer konkreten Klasse –

+0

Thx für Erklärung getan werden. Ich habe jedoch keinen Zugriff auf den Code der benutzerdefinierten IIdentity-Implementierung. Gibt es eine Problemumgehung? – XIII

0

Machen Sie sich über die Benutzeroberfläche IIdentity lustig oder spotten Sie über Ihren benutzerdefinierten Typ?

Ohne ein vollständigeres Code-Snippet zu betrachten, vermute ich, dass es sich beschwert, dass das IsAuthenticated in Ihrer benutzerdefinierten Implementierung nicht als virtuell markiert ist. Dies könnte jedoch nur dann der Fall sein, wenn Sie sich über den konkreten Typ und nicht über die Schnittstelle lustig machen würden.

+0

Ich spotte tatsächlich gegen die konkrete Klasse, da dies eine benutzerdefinierte Implementierung von IIdentity von einem anderen Team ist, das als Assembly geliefert wird. Die IsAuthenticated-Eigenschaft ist nicht virtuell (noch ist die LoginName-Eigenschaft). – XIII

+0

ok - dann müssen Sie IsAuthenticated als virtuell in Ihrer konkreten Klasse markieren. Dies sollte das Problem beheben. –

+0

Wenn Sie Ihre Antworten unten lesen, scheint es, als hätten Sie keine Möglichkeit, dies als virtuell zu markieren. In diesem Fall * möchten * Sie möglicherweise in Betracht ziehen, Ihre eigene * wrapper * -Klasse um die Klasse "unmousable" zu setzen und diese in Ihrem Code zu verwenden. Sie können dann sicherstellen, dass der Wrapper mockfähig ist. Siehe einen Beitrag von mir von vor ein paar Tagen zu diesem Thema: http://StackOverflow.com/Questions/1182338/1182430#1182430 –