Question

I'm attempting to provide a mock that will help me test:

ClaimsPrincipal princple = Thread.CurrentPrincipal as ClaimsPrincipal;

However from what I can tell, the "as" keyword returns null even though I can see in the debugger Thread.CurrentPrincipal is the mock.

To test the theory I put together this short demo:

void Main()
{
    var userMock = new Mock<IUser>();
    userMock.Setup(w => w.UserId).Returns(1);

    var user = userMock.Object as User;

    user.Dump(); // null

}

public interface IUser
{
    int UserId { get; set; }
}

public class User : IUser
{
    public int UserId { get; set; }
}

How can I provide moq's for code that use the as keyword in the background?

From what I understand perhaps I need to provide a way for the proxy to cast back?

I sort of realise that this isn't possible, but wondered what people's approaches are to solving this.

Was it helpful?

Solution 2

I think I've found a work around, I understand I should be mocking against interfaces and shouldn't mock concrete classes, but this may have to do until I can refactor the dependencies.

The trick is to mock the concrete class Mock<User>() and use the As<IUser>() to mock the properties etc.

void Main()
{
    var userMock = new Mock<User>();
    userMock.As<IUser>().Setup(w => w.UserId).Returns(1);

    var user = userMock.Object as User;

    user.Dump(); // not null
}

public interface IUser
{
    int UserId { get; set; }
}

public class User : IUser
{
    public int UserId { get; set; }
}

I think I missed trying this as I've been always mocking to the interfaces in the past.

OTHER TIPS

When you create mock

var userMock = new Mock<IUser>();

then Moq dynamically creates class which implements IUser interface. That class has no relation to other implementations of this interface (like User class). That's why mock object is IUser but it is not User:

var user = userMock.Object as User; // will be null
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top