Question

I have mvc application and I'm working with poco objects and writing unit test. Problem is that all my test fail when they reach this line of code Roles.IsUserInRole("someUser", "role"). Should I implement new interface or repository for Roles or...? Thx

Was it helpful?

Solution

I had the same problem when trying to mock the Roles.IsUserInRole functionality in my coded unit tests. My solution was to create a new class called RoleProvider and an interface with method IsUserInRole which then called the System.Web.Security.Roles.IsUserInRole:

public class RoleProvider: IRoleProvider
{
    public bool IsUserInRole(IPrincipal userPrincipal)
    {
        return System.Web.Security.Roles.IsUserInRole(userPrincipal.Identity.Name, "User");
    }
}

Then in my code I call the RoleProvider IsUserInRole method. As you have an interface you can then mock the IRoleProvider in your tests, example shown here is using Rhino Mocks:

var roleProvider = MockRepository.GenerateStub<IRoleProvider>();
roleProvider.Expect(rp => rp.IsUserInRole(userPrincipal)).Return(true);

Hope this helps.

OTHER TIPS

You can set up a custom method to check roles that will behave differently in tests, but I prefer to have the tests set up a context that will work with the standard methods.

http://stephenwalther.com/blog/archive/2008/07/01/asp-net-mvc-tip-12-faking-the-controller-context.aspx

You could create a light wrapper with a Predicate/Func.

public static Predicate<string> IsUserInRole = role => Roles.IsUserInRole(role);

Then use IsUserInRole() instead of Roles.IsUserInRole(). At run time you get the same behavior. But at test time you can override the function so that it doesn't access the RoleProvider

MyClass.IsUserInRole = role => true;

If you prefer to not have a public static you could inject the Predicate via your constructor and store it as a private readonly.

class MyClass
{    
    private readonly Predicate<string> IsUserInRole;
    MyClass(Predicate<string> roleChecker) { this.IsUserInRole = roleChecker }
    MyClass() : this(role => Roles.IsUserInRole(role)) { }
}

If you use Moq you can return a mock and then control the return value and/or check the method was called. And check what parameter value was sent to the Predicate.

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());
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top