Moq custom IIdentity

2019-07-29 05:04发布

问题:

I created a custom RoleProvider (standard webforms, no mvc) and I would like to test it. The provider itself integrates with a custom implementation of IIdentity (with some added properties).

I have this at the moment:

var user = new Mock<IPrincipal>();
var identity = new Mock<CustomIdentity>();

user.Setup(ctx => ctx.Identity).Returns(identity.Object);
identity.SetupGet(id => id.IsAuthenticated).Returns(true);
identity.SetupGet(id => id.LoginName).Returns("test");

// IsAuthenticated is the implementation of the IIdentity interface and LoginName 

However when I run this test in VS2008 then I get the following error message:

Invalid setup on a non-overridable member: id => id.IsAuthenticated

Why is this happening? And most important, what do I need to do to solve it?

Grz, Kris.

回答1:

You should mock IIdentity (instead of CustomIdentity - only possible if the variables you are mocking are declared in the interface) or declare the used variables as virtual.


To mark as virtual, do this: In your concrete class CustomIdentity, use

public virtual bool isAuthenticated { get; set; }

instead of

public bool isAuthenticated { get; set; }

Moq and other free mocking frameworks doesn't let you mock members and methods of concrete class types, unless they are marked virtual.

Finally, you could create the mock yourself manually. You could inherit CustomIdentity to a test class, which would return the values as you wanted. Something like:

internal class CustomIdentityTestClass : CustomIdentity
{
    public new bool isAuthenticated
    {
        get
        {
            return true;
        }
    }

    public new string LoginName
    {
        get
        {
            return "test";
        }
    }

}

This class would be only used in testing, as a mock for your CustomIdentity.

--EDIT

Answer to question in comments.



回答2:

Are you mocking against the interface IIdentity, or mocking against your custom type?

Without having a fuller code snippet to look at, I am guessing that it is complaining that the IsAuthenticated is not marked as virtual in your custom implementation. However, this could only be the case if you were mocking against the concrete type, not the interface.