Mocking Systems Resources in C#/ASP.NET

Static System Resources

When writing unit tests in C#, one question that often comes up is how to mock static resources, and which static resources make sense to mock in the first place. I tend to think of this in terms of whether or not the static resource is doing something that I can’t directly control. For instance, I wouldn’t mock string.IsNullOrEmpty. It's a pure function, meaning that it has no side effects, and given the same input, it will always return the same output. It also doesn't rely on any external data.

public interface IDateTimeService
{
DateTime UtcNow { get; }
}

public class DateTimeService : IDateTimeService
{
public DateTime UtcNow => DateTime.UtcNow;
}

ASP.NET Context

This technique also works really well for values in the HttpContext that you don’t have control of because it’s expected that the ASP.NET runtime will set these values for you. How do you mock these? A good example is mocking the user principle. I want to be able to write unit tests where I can control what, and if, the User ID is set. In the case of one of the projects I’m working on, this is an integer value, and it resides in the http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier claim. The code for this looks as follows:

public interface IPrincipalService
{
int UserId { get; }
}

public class PrincipalService : IPrincipalService
{
private readonly IHttpContextAccessor _httpContextAccessor;

public PrincipalService(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}

public int UserId
{
get
{
var claimsPrincipal = _httpContextAccessor.HttpContext?.User;
if (claimsPrincipal == null)
throw new MissingClaimsPrincipalException();

return int.Parse(claimsPrincipal.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? "", CultureInfo.CurrentCulture);
}
}
}

I’m a Full-stack Software Engineer and Architect living and working in the Portland, OR Metro area, specializing in .NET and web technologies.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store