Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 单元测试-如何将控制器用户设置为通用主体对象_C#_Unit Testing_Asp.net Web Api_Tdd_Asp.net Apicontroller - Fatal编程技术网

C# 单元测试-如何将控制器用户设置为通用主体对象

C# 单元测试-如何将控制器用户设置为通用主体对象,c#,unit-testing,asp.net-web-api,tdd,asp.net-apicontroller,C#,Unit Testing,Asp.net Web Api,Tdd,Asp.net Apicontroller,更新的完整解决方案: 我将要测试的WebApi控制器方法: using Microsoft.AspNet.Identity; using System.Web.Http; [Authorize] public class GigsController : ApiController { private readonly IUnitOfWork _unitOfWork; public GigsController(IUnitOfWork unitOfWork) {

更新的完整解决方案:

我将要测试的WebApi控制器方法:

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();
    }
}
单元测试类:

[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;
    }
[TestClass]
公共类GigsController测试
{
专用GigsController\u控制器;
公共GigsController测试()
{
变量标识=新的GenericEntity(“user1@domain.com");
identity.AddClaim(
新索赔(”http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", "user1@domain.com"));
identity.AddClaim(
新索赔(”http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", "1"));
var principal=新的GenericPrincipal(标识,null);
var mockUoW=new Mock();
_控制器=新的GigsController(mockUoW.Object);
_controller.User=principal;
}
我发现以下错误:

错误CS0200属性或索引器“ApiController.User”不能为空 分配给--它是只读的


而是设置执行线程的
CurrentPrincipal

Thread.CurrentPrincipal = principal;

您可以通过
ControllerContext

var user = new ClaimsPrincipal();
var context = new ControllerContext
{
    HttpContext = new DefaultHttpContext
    {
        User = user
    }
};

controllerUnderTest.ControllerContext = context;

我在学习Moshi的教程时遇到了同样的问题,这让我困惑了好几个小时才最终解决了这个问题

最终,为我解决这个问题的是将我的using语句从:

使用GigHub.Controllers

使用GigHub.Controllers.Api

您的GigsController\u控制器指向的是控制器本身,而不是ApicController。我有点希望Moshi在其Api类的名称中添加“Api”,这样您就可以知道您是在查看纯控制器还是控制器的Api版本,而不必检查名称空间或查看对象的定义

您是对的,控制器类的User属性实际上只有一个Get

public abstract class Controller : ControllerBase, IActionFilter, 
IAuthenticationFilter, IAuthorizationFilter, IDisposable, IExceptionFilter, 
IResultFilter, IAsyncController, IController, IAsyncManagerContainer
{
   public IPrincipal User { get; }
}
但是,ApicController类的用户属性同时具有Get和Set

public abstract class ApiController : IHttpController, IDisposable
{
    public IPrincipal User { get; set; }
}
希望这也是你的问题,能帮助你解决


干杯!

当我试图模仿控制器中的用户而不是controller.api时,我看到了这篇文章,并且很挣扎。 无论如何,这样做的方法是用模拟对象覆盖控制器中的ControllerContext,然后将模拟对象设置为返回要模拟的用户

var user = CreateLoggedInUser(targetUserID);

mockControllerContext = new Mock<ControllerContext>();

mockControllerContext.Setup(o => o.HttpContext.User).Returns(user);

myCaseController.ControllerContext = mockControllerContext.Object;
var user=CreateLoggedInUser(targetUserID);
mockControllerContext=新建Mock();
mockControllerContext.Setup(o=>o.HttpContext.User).Returns(User);
myCaseController.ControllerContext=mockControllerContext.Object;

private-ClaimsPrincipal-CreateLoggedInUser(int-userID)
{
GenericEntity myIdentity=新GenericEntity(“apiTestUser”);
myIdentity.AddClaims(新列表{
新声明(ClaimTypes.Sid,userID.ToString()),
});
返回新的ClaimsPrincipal(myIdentity);
}

这是不正确的。不是只读的。因此您需要提供一个可用于重现问题的声明。这样我们可以更好地评估问题的真正原因。嗨,Nkosi,我已经更新了完整的解决方案,它仍然显示ApiController。用户也是readonlyShow
GigsController
声明。刚刚更新的mate:)I u使用提供的代码试图重现您的问题,但正如预期的那样,代码进行编译,允许将值分配给
ApiController.User
属性。除非您在示例中显示的内容有其他内容,否则无法重现您显示的错误。情况不同。
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);
    }