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("[email protected]");
identity.AddClaim(
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", "[email protected]"));
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
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!