2010-11-23 52 views
9

我目前正在開發一個asp.net mvc 2應用程序,它使用默認的SqlMembershipProvider進行身份驗證。我實現了一個控制器方法,通過調用Membership.GetUser().ProviderUserKey讀取當前用戶的ProviderUserKey。 現在我正在嘗試爲該控制器編寫一些測試方法。嘲笑會員用戶

擺脫對靜態成員類扶養的,我創建了一個簡單封裝,使我的控制依賴於相應的接口上:

public interface IStaticMembershipService { 
    MembershipUser GetUser(); 

    void UpdateUser(MembershipUser user); 
} 

到目前爲止一切正常,但爲了單位 - 測試控制器,我仍然需要模擬此接口的GetUser()方法並返回一個包含ProviderUserKey屬性的MembershipUser對象。嘲笑這樣的對象最簡單的方法是什麼?

我使用moq作爲嘲諷框架。

回答

11

它會是這個樣子:

var membershipMock = new Mock<IStaticMembershipService>(); 
var userMock = new Mock<MembershipUser>(); 
userMock.Setup(u => u.ProviderUserKey).Returns(guid); 
membershipMock.Setup(s => s.GetUser()).Returns(userMock.Object); 

如果類的MembershipUser不借給自己嘲諷(即如果ProviderUserKey不虛),您需要創建自己的對象來代表您將需要從MembershipUser對象獲取的值,並讓您的服務返回其中一個對象。

還有輕微的可能性,即一個的MembershipUser是POCO類對象,你可以創建這樣一個實例:

var userMock = new MembershipUser {ProviderUserKey = guid}; 
+0

非常感謝,創建MembershipUser-class的模擬效果很好。 – Simon 2010-11-24 09:05:54

1

事情與此類似:

var user = new MembershipUser(); 
var membershipService = new Mock<IStaticMembershipService>(); 
membershipService.Setup(p => p.GetUser()).Returns(user); 
2

我認爲你需要從界面消費者真正分開的實現細節關心。我不確定你的控件需要ProviderUserKey,如果它將它轉換爲特定的類,但我會考慮讓你的界面真正滿足控制器的需求,而不是相反。喜歡的東西(不知道更多細節):

public interface IMembershipDetailsService { 
    Guid UserKey { get; } 
} 

一旦你做的這個抽象級別,然後嘲諷變得更加容易,因爲你可能只是做:

membershipService.Setup (svc => svc.UserKey).Returns (myGuid); 

只是一種思路,而不是試圖返回一個完整的MembershipUser對象,你需要進一步存根。

+0

+1非常好的一點。 – StriplingWarrior 2010-11-27 17:59:03

0

如果你需要模擬出HttpContext的東西,你可以做類似下面的東西嗎..下面是使用NUnitMoq

[SetUp] 
private void Setup() 
{ 
    _mockHttpContext = new Mock<HttpContextBase>(); 
    _mockStaticMembership = new Mock<IStaticMembershipService>();   
    _mockUser = new Mock<MembershipUser>(); 
    _mockPrincipalUser = new Mock<IPrincipal>();   

    _mockHttpContext.Setup(http => http.User).Returns(_mockPrincipalUser.Object); 
    _mockPrincipalUser.Setup(principal => principal.Identity.Name).Returns("myname"); 
    _mockUser.Setup(user => user.ProviderUserKey).Returns(Guid.NewGuid()); 

    _mockStaticMembership.Setup(membership => membership.GetUser(It.IsAny<string>())).Returns(_mockUser.Object); 

} 

[Test] 
public void Some_Test_For_My_Controller() 
{    
    var controller = new MyController(_mockStaticMembership.Object);    
    controller.ControllerContext = new ControllerContext(_mockHttpContext.Object, new RouteData(), controller); 

    //Test your action and verify 
}