2010-11-23 77 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 
}