我有 mvc 应用程序,我正在使用 poco 对象并编写单元测试。问题是当他们到达这行代码 Roles.IsUserInRole("someUser", "role") 时,我的所有测试都失败了。我应该为角色实现新的接口或存储库还是......?谢谢
问问题
2982 次
3 回答
11
在我的编码单元测试中尝试模拟 Roles.IsUserInRole 功能时,我遇到了同样的问题。我的解决方案是创建一个名为 RoleProvider 的新类和一个带有方法 IsUserInRole 的接口,然后调用 System.Web.Security.Roles.IsUserInRole:
public class RoleProvider: IRoleProvider
{
public bool IsUserInRole(IPrincipal userPrincipal)
{
return System.Web.Security.Roles.IsUserInRole(userPrincipal.Identity.Name, "User");
}
}
然后在我的代码中,我调用 RoleProvider IsUserInRole 方法。由于您有一个接口,因此您可以在测试中模拟 IRoleProvider,此处显示的示例是使用 Rhino Mocks:
var roleProvider = MockRepository.GenerateStub<IRoleProvider>();
roleProvider.Expect(rp => rp.IsUserInRole(userPrincipal)).Return(true);
希望这可以帮助。
于 2011-01-04T17:07:05.193 回答
0
您可以设置一个自定义方法来检查在测试中表现不同的角色,但我更喜欢让测试设置一个可以与标准方法一起使用的上下文。
于 2011-01-05T00:35:26.687 回答
0
您可以使用 Predicate/Func 创建一个轻量级包装器。
public static Predicate<string> IsUserInRole = role => Roles.IsUserInRole(role);
然后使用 IsUserInRole() 而不是 Roles.IsUserInRole()。在运行时,您会得到相同的行为。但是在测试时,您可以覆盖该函数,使其不访问 RoleProvider
MyClass.IsUserInRole = role => true;
如果您不想拥有公共静态,您可以通过构造函数注入谓词并将其存储为私有只读。
class MyClass
{
private readonly Predicate<string> IsUserInRole;
MyClass(Predicate<string> roleChecker) { this.IsUserInRole = roleChecker }
MyClass() : this(role => Roles.IsUserInRole(role)) { }
}
如果你使用 Moq,你可以返回一个 mock,然后控制返回值和/或检查方法是否被调用。并检查发送到谓词的参数值。
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());
于 2015-02-25T21:32:42.697 回答