Search code examples
c#unit-testingmoqas-keyword

moq and the "as" keyword


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.


Solution

  • 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.