我目前正在开发一个asp.net mvc 2应用程序,它使用默认的SqlMembershipProvider进行身份验证。我已经实现了一个控制器方法,通过调用Membership.GetUser().ProviderUserKey
来读取当前用户的ProviderUserKey。
现在我正在尝试为这个控制器编写一些测试方法。
为了摆脱静态Membership类的依赖性,我创建了一个瘦包装器并使我的控制器依赖于相应的接口:
public interface IStaticMembershipService {
MembershipUser GetUser();
void UpdateUser(MembershipUser user);
}
到目前为止一切正常,但为了对控制器进行单元测试,我仍然需要模拟此接口的GetUser()
方法并返回包含ProviderUserKey属性的MembershipUser对象。模拟这样一个对象最简单的方法是什么?
我正在使用moq作为模拟框架。
答案 0 :(得分: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};
答案 1 :(得分:2)
我认为您需要将实现细节与消费者真正关心的界面分开。我不确定你的控件需要ProviderUserKey,如果它将它转换为特定的类等,但我会考虑让你的界面真正满足控制器的需求,而不是相反。类似的东西(不知道更多细节):
public interface IMembershipDetailsService {
Guid UserKey { get; }
}
一旦你进行了这种抽象级别,那么模拟变得更容易,因为你可以这样做:
membershipService.Setup (svc => svc.UserKey).Returns (myGuid);
只是另一个想法,而不是尝试返回整个MembershipUser对象,你需要进一步存根。
答案 2 :(得分:1)
类似的东西:
var user = new MembershipUser();
var membershipService = new Mock<IStaticMembershipService>();
membershipService.Setup(p => p.GetUser()).Returns(user);
答案 3 :(得分:0)
如果你需要模拟HttpContext的东西,你可以做下面的事吗......下面是使用NUnit和Moq。
[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
}