Updated full solution:
WebApi Controller method which I'm going to test :
using Microsoft.AspNet.Identity;
using System.Web.Http;
[Authorize]
public class GigsController : ApiController
{
private readonly IUnitOfWork _unitOfWork;
public GigsController(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
[HttpDelete]
public IHttpActionResult Cancel(int id)
{
var userId = User.Identity.GetUserId();
var gig = _unitOfWork.Gigs.GetGigWithAttendees(id);
if (gig.IsCanceled)
return NotFound();
if (gig.ArtistId != userId)
return Unauthorized();
gig.Cancel();
_unitOfWork.Complete();
return Ok();
}
}
Unit Test class :
[TestClass]
public class GigsControllerTests
{
private GigsController _controller;
public GigsControllerTests()
{
var identity = new GenericIdentity("user1#domain.com");
identity.AddClaim(
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", "user1#domain.com"));
identity.AddClaim(
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", "1"));
var principal = new GenericPrincipal(identity, null);
var mockUoW = new Mock<IUnitOfWork>();
_controller = new GigsController(mockUoW.Object);
_controller.User = principal;
}
I'm getting following error :
Error CS0200 Property or indexer 'ApiController.User' cannot be
assigned to -- it is read only
https://i.stack.imgur.com/YDQJS.png
You can assign it through ControllerContext
var user = new ClaimsPrincipal();
var context = new ControllerContext
{
HttpContext = new DefaultHttpContext
{
User = user
}
};
controllerUnderTest.ControllerContext = context;
I ran into this same issue while following Moshi's tutorials, and this stumped me for a good couple of hours before I was finally able to resolve this.
Ultimately, what fixed this for me was changing my using statement from:
using GigHub.Controllers;
to
using GigHub.Controllers.Api;
Your GigsController _controller is pointing to the Controller itself and not the ApiController. I kinda wish Moshi had put "Api" in the name of his API classes that way you'd know if you were looking at the pure controller or the API version of the controller without having to check namespaces or go to definition on your objects.
You're right that the User property for the Controller class does indeed only have a Get.
public abstract class Controller : ControllerBase, IActionFilter,
IAuthenticationFilter, IAuthorizationFilter, IDisposable, IExceptionFilter,
IResultFilter, IAsyncController, IController, IAsyncManagerContainer
{
public IPrincipal User { get; }
}
The User property for the ApiController class however has both a Get and Set.
public abstract class ApiController : IHttpController, IDisposable
{
public IPrincipal User { get; set; }
}
Hopefully this was your issue as well and helps you out!
Cheers!
Instead set the CurrentPrincipal of your executing thread
Thread.CurrentPrincipal = principal;
Came across this post when I'm trying to mock a user in a controller, rather than controller.apiā¦ and struggled.
Anyway the way to do it is by overwriting ControllerContext in the controller with a mock object , and the mock object is set up to return the user you wish to mock.
var user = CreateLoggedInUser(targetUserID);
mockControllerContext = new Mock<ControllerContext>();
mockControllerContext.Setup(o => o.HttpContext.User).Returns(user);
myCaseController.ControllerContext = mockControllerContext.Object;
and
private ClaimsPrincipal CreateLoggedInUser(int userID)
{
GenericIdentity myIdentity = new GenericIdentity("apiTestUser");
myIdentity.AddClaims(new List<Claim> {
new Claim(ClaimTypes.Sid, userID.ToString()),
});
return new ClaimsPrincipal(myIdentity);
}
Related
In few places in legacy code (more than 100 controllers), we are running action from other controllers.
In .NET Framework it runs OK - ClaimsPrincipal in both controller's action have correct values, but in .NET Core, running SecondController.internalPut() from FirstController gives me NullReferenceException.
FirstController:
[EnableCors]
public class FirstController : BaseApiController
{
public FirstController(IContextFactory contextFactory) : base(contextFactory)
{
}
[HttpPut]
[HttpPost]
[Route("/api/firstcontroller")]
public IActionResult Put([FromBody] MyDTO data)
{
var token = Identity.Token; // <--- correct value
var secondController = new SecondController(ContextFactory);
secondController.internalPut(something); <--- NullReferenceException
return Ok();
}
}
SecondController:
[EnableCors]
public class SecondController : BaseApiController
{
public SecondController(IContextFactory contextFactory) : base(contextFactory)
{
}
[HttpPut]
[HttpPost]
public async Task<IActionResult> Put(Guid myGuid)
{
internalPut(something); // <-- OK
return Ok();
}
internal void internalPut(object something)
{
var token = Identity.Token; // <--- NullReferenceException when running from FirstController!!
}
}
And BaseApiController with TokenIdentity:
[ApiController]
[Route("/api/[controller]")]
[Route("/api/[controller]/[action]")]
public class BaseApiController : ControllerBase
{
protected readonly IMyContextFactory ContextFactory;
public BaseApiController(IMyContextFactory contextFactory)
{
ContextFactory = contextFactory;
}
public TokenIdentity Identity => User?.Identity as TokenIdentity;
}
public class TokenIdentity : GenericIdentity
{
public Guid Token { get; set; }
public string User { get; set; }
public TokenIdentity(Guid token) : base(token.ToString())
{
Token = token;
}
}
How is the easiest fix for this bug? I know that I can change BaseApiController implementation to get ClaimsPrincipal from IHttpContextAccessor, but this means that I need to update constructors for all > 100 controllers in code...
It is another way to always have ClaimsPrincipal when we are calling action from another controller?
What I recommend as the correct solution
I can't emphasise enough how much I recommend moving shared functionality into its own services, or perhaps look at using the Mediator Pattern (e.g. using the MediatR library) to decouple your controllers from their functionality a little. What I provide below is not a solution, but a band-aid.
What I recommend a QUICK FIX only
Why is this only a quick fix?: because this doesn't instantiate the correct action details and route parameters, so it could potentially cause you some hard-to-find bugs, weird behaviour, URLs maybe not generating correctly (if you use this), etc.
Why am I recommending it?: because I know that sometimes time is not on our side and that perhaps you need a quick fix to get this working while you work on a better solution.
Hacky quick fix
You could add the following method to your base controller class:
private TController CreateController<TController>() where TController: ControllerBase
{
var actionDescriptor = new ControllerActionDescriptor()
{
ControllerTypeInfo = typeof(TController).GetTypeInfo()
};
var controllerFactory = this.HttpContext.RequestServices.GetRequiredService<IControllerFactoryProvider>().CreateControllerFactory(actionDescriptor);
return controllerFactory(this.ControllerContext) as TController;
}
Then instead of var secondController = new SecondController(ContextFactory); you would write:
var secondController = CreateController<SecondController>();
I want to know how to use Moq for mocking my EF Core's DbContext when I am using DI to provide my Database context to the controller as shown below:
public class RegisterController : Controller
{
private AppDbContext context;
public RegisterController(AppDbContext appDbContext)
{
context = appDbContext;
}
public IActionResult Create()
{
return View();
}
[HttpPost]
public async Task<IActionResult> Create(Register register)
{
if (ModelState.IsValid)
{
context.Add(register);
await context.SaveChangesAsync();
return RedirectToAction("Read");
}
else
return View();
}
}
Here AppDbContext is my database context for the EF core.
I want to write test case for the Create action. I have tried the below code:
[Fact]
public async Task Test_Create_POST_ValidModelState()
{
// Arrange
var r = new Register()
{
Id = 4,
Name = "Test Four",
Age = 59
};
var mockRepo = new Mock<AppDbContext>();
mockRepo.Setup(repo => repo.CreateAsync(It.IsAny<Register>()))
.Returns(Task.CompletedTask)
.Verifiable();
var controller = new RegisterController(mockRepo.Object);
// Act
var result = await controller.Create(r);
// Assert
var redirectToActionResult = Assert.IsType<RedirectToActionResult>(result);
Assert.Null(redirectToActionResult.ControllerName);
Assert.Equal("Read", redirectToActionResult.ActionName);
mockRepo.Verify();
}
The main problem here is that I cannot do:
var mockRepo = new Mock<AppDbContext>();
I want to follow this approach as I have already added in-memory database.
Note that I know there is a another way to test with repository pattern. Which can be done by changing the create action as:
public class RegisterController : Controller
{
private IRegisterRepository context;
public RegisterController(IRegisterRepository appDbContext)
{
context = appDbContext;
}
public IActionResult Create()
{
return View();
}
[HttpPost]
public async Task<IActionResult> Create(Register register)
{
if (ModelState.IsValid)
{
await context.CreateAsync(register);
return RedirectToAction("Read");
}
else
return View();
}
}
Where the interface IRegisterRepository and RegisterRepository.cs codes are:
public interface IRegisterRepository
{
Task CreateAsync(Register register);
}
public class RegisterRepository : IRegisterRepository
{
private readonly AppDbContext context;
public RegisterRepository(AppDbContext dbContext)
{
context = dbContext;
}
public Task CreateAsync(Register register)
{
context.Register.Add(register);
return context.SaveChangesAsync();
}
}
and the startup.cs code which add it as a service is:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<AppDbContext>(optionsBuilder => optionsBuilder.UseInMemoryDatabase("InMemoryDb"));
services.AddScoped<IRegisterRepository, RegisterRepository>();
services.AddControllersWithViews();
}
I do not want to follow this approach (the repository pattern). I want to fake database context directly because I want to directly do the insertion of the record in the create action as the controller is getting database context object in it's constructor.
So how to write fake database context using moq in this test methods here?
Don't mock DbContext, because tests with mocking dbContext will not provide good quality feedback for developer.
Mocked DbContext will verify only that some method are called, which will convert code maintenance (refactoring) into a nightmare.
Instead use In-Memory provider or Sqlite provider with "in-memory" feature.
EF Core In-Memory Database Provider
Using SQLite to test an EF Core application
Alternative approach is to test against actual database - such tests will provide more confidence that application works correctly in "production" environment.
There are several really useful libraries which does support what you are looking for.
Here are two of my favourite ones:
EntityFrameworkCore3Mock
Github repo
The only prerequisite is that you have to define your DbSet as virtual.
public class AppDbContext: DbContext
{
public virtual DbSet<Entity> Entities { get; set; }
}
Then the mocking would be this easy:
var initialEntities = new[]
{
new Entity { ... },
new Entity { ... },
};
var dbContextMock = new DbContextMock<AppDbContext>(DummyOptions);
var usersDbSetMock = dbContextMock.CreateDbSetMock(x => x.Entities, initialEntities);
EntityFrameworkCore.Testing
Github repo
The only difference here is how you initialize the table with data:
var initialEntities = new[]
{
new Entity { ... },
new Entity { ... },
};
var dbContextMock = Create.MockedDbContextFor<AppDbContext>();
dbContextMock.Set<Entity>().AddRange(initialEntities);
dbContextMock.SaveChanges();
I have an Asp.net core 2 Web api. and I'm trying to implement a custom authorisation filter.
At the moment I have the following:
public class AuthorisationAttribute : TypeFilterAttribute
{
public AuthorisationAttribute() : base(typeof(AuthorisationFilter))
{
Arguments = new object[] { new Claim(ClaimTypes.UserData, "will be my user data") };
}
}
public class AuthorisationFilter : IAuthorizationFilter
{
readonly HttpContext _httpContext;
public AuthorisationFilter(HttpContext httpContext)
{
_httpContext = httpContext;
}
public void OnAuthorization(AuthorizationFilterContext context)
{
var authorisationCookie = context.HttpContext.Request.Headers.Where(t => t.Key == "auth").FirstOrDefault();
var temp = new JwtSecurityTokenHandler();
var unencryptedToken = temp.ReadToken(authorisationCookie.Value) as JwtSecurityToken;
var session = _httpContext.Session;
//MORE TO DO HERE YET! Just want to test getting called when expected.
return;
}
}
Then on a controller method I Have:
public class HomeController : Controller
{
[Authorisation(),HttpGet]
public IActionResult Index()
{
return View("~/Views/Home/Index.cshtml");
}
}
When I run the application The authorisationAttribute constructor gets called. At the point I try to call the controller Method I receive the following Error:
InvalidOperationException: A suitable constructor for type
AuthorisationFilter; could not be located. Ensure the type is concrete
and services are registered for all parameters of a public
constructor.
So in my startup.cs file I also added:
services.AddScoped<IAuthorizationFilter, AuthorisationFilter>();
but it's made no difference
The built-in DI does not know anything about the current HttpContext, first you have to add the IHttpContextAccessor to the service collection:
services.AddHttpContextAccessor();
Then you can get it as your filters constructor argument:
public AuthorisationFilter(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
Then you can access to the current HttpContext via _httpContextAccessor.HttpContext.
However you can also access the current HttpContext through your AuthorizationFilterContext like you already use that in your sample code:
context.HttpContext
Edit: As you are setting the Argument property of the TypeFilterAttribute you have to make a constructor in your filter that uses that argument, so like:
public AuthorisationFilter(Claim claim)
{
}
I'm extending the ApplicationUser class by adding a new property (as shown in the tutorial
Create an ASP.NET MVC 5 App with Facebook and Google OAuth2 and OpenID Sign-on (C#))
public class ApplicationUser : IdentityUser
{
public DateTime BirthDate { get; set; }
}
Now I want to create a Unit Test to verify that my AccountController is correctly saving the BirthDate.
I've created an in-memory user store named TestUserStore
[TestMethod]
public void Register()
{
// Arrange
var userManager = new UserManager<ApplicationUser>(new TestUserStore<ApplicationUser>());
var controller = new AccountController(userManager);
// This will setup a fake HttpContext using Moq
controller.SetFakeControllerContext();
// Act
var result =
controller.Register(new RegisterViewModel
{
BirthDate = TestBirthDate,
UserName = TestUser,
Password = TestUserPassword,
ConfirmPassword = TestUserPassword
}).Result;
// Assert
Assert.IsNotNull(result);
var addedUser = userManager.FindByName(TestUser);
Assert.IsNotNull(addedUser);
Assert.AreEqual(TestBirthDate, addedUser.BirthDate);
}
The controller.Register method is boilerplate code generated by MVC5 but for reference purposes I'm including it here.
// POST: /Account/Register
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser() { UserName = model.UserName, BirthDate = model.BirthDate };
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
await SignInAsync(user, isPersistent: false);
return RedirectToAction("Index", "Home");
}
else
{
AddErrors(result);
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
When I call Register, it calls SignInAsync which is where the trouble will occur.
private async Task SignInAsync(ApplicationUser user, bool isPersistent)
{
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
}
At the lowest layer, the boilerplate code includes this tidbit
private IAuthenticationManager AuthenticationManager
{
get
{
return HttpContext.GetOwinContext().Authentication;
}
}
This is where the root of the problm occurs. This call to GetOwinContext is an extension method which I cannot mock and I cannot replace with a stub (unless of course I change the boilerplate code).
When I run this test I get an exception
Test method MVCLabMigration.Tests.Controllers.AccountControllerTest.Register threw exception:
System.AggregateException: One or more errors occurred. ---> System.NullReferenceException: Object reference not set to an instance of an object.
at System.Web.HttpContextBaseExtensions.GetOwinEnvironment(HttpContextBase context)
at System.Web.HttpContextBaseExtensions.GetOwinContext(HttpContextBase context)
at MVCLabMigration.Controllers.AccountController.get_AuthenticationManager() in AccountController.cs: line 330
at MVCLabMigration.Controllers.AccountController.<SignInAsync>d__40.MoveNext() in AccountController.cs: line 336
In prior releases the ASP.NET MVC team worked very hard to make the code testable. It seems on the surface that now testing an AccountController is not going to be easy. I have some choices.
I can
Modify the boiler plate code so that it doesn't call an extension method and deal with this problem at that level
Setup the OWin pipeline for testing purposes
Avoid writing testing code that requires the AuthN / AuthZ infrastructure (not a reasonable option)
I'm not sure which road is better. Either one could solve this. My question boils down to which is the best strategy.
Note: Yes, I know that I don't need to test code that I didn't write. The UserManager infrastructure provided MVC5 is such a piece of infrastructure BUT if I want to write tests that verify my modifications to ApplicationUser or code that verifies behavior that depends upon user roles then I must test using UserManager.
I'm answering my own question so I can get a sense from the community if you think this is a good answer.
Step 1: Modify the generated AccountController to provide a property setter for the AuthenticationManager using a backing field.
// Add this private variable
private IAuthenticationManager _authnManager;
// Modified this from private to public and add the setter
public IAuthenticationManager AuthenticationManager
{
get
{
if (_authnManager == null)
_authnManager = HttpContext.GetOwinContext().Authentication;
return _authnManager;
}
set { _authnManager = value; }
}
Step 2:
Modify the unit test to add a mock for the Microsoft.OWin.IAuthenticationManager interface
[TestMethod]
public void Register()
{
// Arrange
var userManager = new UserManager<ApplicationUser>(new TestUserStore<ApplicationUser>());
var controller = new AccountController(userManager);
controller.SetFakeControllerContext();
// Modify the test to setup a mock IAuthenticationManager
var mockAuthenticationManager = new Mock<IAuthenticationManager>();
mockAuthenticationManager.Setup(am => am.SignOut());
mockAuthenticationManager.Setup(am => am.SignIn());
// Add it to the controller - this is why you have to make a public setter
controller.AuthenticationManager = mockAuthenticationManager.Object;
// Act
var result =
controller.Register(new RegisterViewModel
{
BirthDate = TestBirthDate,
UserName = TestUser,
Password = TestUserPassword,
ConfirmPassword = TestUserPassword
}).Result;
// Assert
Assert.IsNotNull(result);
var addedUser = userManager.FindByName(TestUser);
Assert.IsNotNull(addedUser);
Assert.AreEqual(TestBirthDate, addedUser.BirthDate);
}
Now the test passes.
Good idea? Bad idea?
My needs are similar, but I realized that I don't want a pure unit test of my AccountController. Rather I want to test it in an environment that is as close as possible to its natural habitat (integration test, if you want). So I don't want to mock the surrounding objects, but use the real ones, with as little of my own code as I can get away with.
The HttpContextBaseExtensions.GetOwinContext method also got in my way, so I was very happy with Blisco's hint.
Now the most important part of my solution looks like this:
/// <summary> Set up an account controller with just enough context to work through the tests. </summary>
/// <param name="userManager"> The user manager to be used </param>
/// <returns>A new account controller</returns>
private static AccountController SetupAccountController(ApplicationUserManager userManager)
{
AccountController controller = new AccountController(userManager);
Uri url = new Uri("https://localhost/Account/ForgotPassword"); // the real string appears to be irrelevant
RouteData routeData = new RouteData();
HttpRequest httpRequest = new HttpRequest("", url.AbsoluteUri, "");
HttpResponse httpResponse = new HttpResponse(null);
HttpContext httpContext = new HttpContext(httpRequest, httpResponse);
Dictionary<string, object> owinEnvironment = new Dictionary<string, object>()
{
{"owin.RequestBody", null}
};
httpContext.Items.Add("owin.Environment", owinEnvironment);
HttpContextWrapper contextWrapper = new HttpContextWrapper(httpContext);
ControllerContext controllerContext = new ControllerContext(contextWrapper, routeData, controller);
controller.ControllerContext = controllerContext;
controller.Url = new UrlHelper(new RequestContext(contextWrapper, routeData));
// We have not found out how to set up this UrlHelper so that we get a real callbackUrl in AccountController.ForgotPassword.
return controller;
}
I have not yet succeeded to get everything working (in particular, I could not get UrlHelper to produce a proper URL in the ForgotPassword method), but most of my needs are covered now.
I've used a solution similar to yours - mocking an IAuthenticationManager - but my login code is in a LoginManager class that takes the IAuthenticationManager via constructor injection.
public LoginHandler(HttpContextBase httpContext, IAuthenticationManager authManager)
{
_httpContext = httpContext;
_authManager = authManager;
}
I'm using Unity to register my dependencies:
public static void RegisterTypes(IUnityContainer container)
{
container.RegisterType<HttpContextBase>(
new InjectionFactory(_ => new HttpContextWrapper(HttpContext.Current)));
container.RegisterType<IOwinContext>(new InjectionFactory(c => c.Resolve<HttpContextBase>().GetOwinContext()));
container.RegisterType<IAuthenticationManager>(
new InjectionFactory(c => c.Resolve<IOwinContext>().Authentication));
container.RegisterType<ILoginHandler, LoginHandler>();
// Further registrations here...
}
However, I'd like to test my Unity registrations, and this has proved tricky without faking (a) HttpContext.Current (hard enough) and (b) GetOwinContext() - which, as you've found, is impossible to do directly.
I've found a solution in the form of Phil Haack's HttpSimulator and some manipulation of the HttpContext to create a basic Owin environment. So far I've found that setting a single dummy Owin variable is enough to make GetOwinContext() work, but YMMV.
public static class HttpSimulatorExtensions
{
public static void SimulateRequestAndOwinContext(this HttpSimulator simulator)
{
simulator.SimulateRequest();
Dictionary<string, object> owinEnvironment = new Dictionary<string, object>()
{
{"owin.RequestBody", null}
};
HttpContext.Current.Items.Add("owin.Environment", owinEnvironment);
}
}
[TestClass]
public class UnityConfigTests
{
[TestMethod]
public void RegisterTypes_RegistersAllDependenciesOfHomeController()
{
IUnityContainer container = UnityConfig.GetConfiguredContainer();
HomeController controller;
using (HttpSimulator simulator = new HttpSimulator())
{
simulator.SimulateRequestAndOwinContext();
controller = container.Resolve<HomeController>();
}
Assert.IsNotNull(controller);
}
}
HttpSimulator may be overkill if your SetFakeControllerContext() method does the job, but it looks like a useful tool for integration testing.
Using C# I'm trying to unit test controller actions and time how long it takes for them to return. I'm using the unit testing framework built into VS2012 Ultimate.
Unfortunately I'm also trying to wrap my head around TestContext and how to use it..
Some example code (my controller action):
[HttpPost]
public JsonResult GetUserListFromWebService()
{
JsonResult jsonResult = new JsonResult();
WebService svc = new WebService();
jsonResult.Data = svc.GetUserList(User.Identity.Name);
return jsonResult;
}
When I try to unit test this, User.Identity.Name is null so it throws an exception. My current unit test code looks like:
[TestClass]
public class ControllerAndRepositoryActionTests {
public TestContext testContext { get; set; }
private static Repository _repository;
private username = "domain\\foobar";
private static bool active = true;
[ClassInitialize]
public static void MyClassInitialize(TestContext testContext)
{
_repository = new WebServiceRepository();
}
#region Controller method tests
[TestMethod]
public void GetUserListReturnsData()
{
Controller controller = new Controller();
var result = controller.GetUserListFromWebService();
Assert.IsNotNull(result.Data);
}
#endregion
#region service repository calls - with timing
[TestMethod]
public void GetUserListTimed()
{
testContext.BeginTimer("Overall");
var results = _repository.GetUserList(username, active);
foreach (var result in results)
{
Console.WriteLine(result.UserID);
Console.WriteLine(result.UserName);
}
testContext.EndTimer("Overall");
}
#endregion
}
Can I use TestContext to set the User.Identity that will be eventually used in the GetUserListFromWebService call?
If I can, what is the accepted way to assign TestContext. When I get it as a param in MyClassInitialize do I set my member variable, or am I supposed to pass it as a param to the TestMethods in some way?
Am I completely missing the point and should I be using some other mocking framework?
To make this test to work, I should change the signature of your class. Because you can not make a stub or a mock of your class Webservice, because you are creating it in the method.
class YourClass
{
private readeonly WebService _ws;
public YourClass(WebService ws)
{
_ws=ws;
}
[HttpPost]
public JsonResult GetUserListFromWebService()
{
JsonResult jsonResult = new JsonResult();
jsonResult.Data = _ws.GetUserList(User.Identity.Name);
return jsonResult;
}
}
Now you can in your test easily mock the class WebService with Moq or other frameworks. To make it eaven easier you shoul create an interface to your class WebService that implements the method GetUserList();
And to mock the User.Identy
public SomeController CreateControllerForUser(string userName)
{
var mock = new Mock<ControllerContext>();
mock.SetupGet(p => p.HttpContext.User.Identity.Name).Returns(userName);
mock.SetupGet(p => p.HttpContext.Request.IsAuthenticated).Returns(true);
var controller = new SomeController();
controller.ControllerContext = mock.Object;
return controller;
}
Or read this blog post http://weblogs.asp.net/rashid/