In früheren Versionen Sie User
direkt am Regler eingestellt haben könnte, was für einige sehr einfache Unit-Tests gemacht.
Wenn Sie den Quellcode für ControllerBase betrachten, werden Sie feststellen, dass User
aus HttpContext
extrahiert wird.
/// <summary>
/// Gets or sets the <see cref="ClaimsPrincipal"/> for user associated with the executing action.
/// </summary>
public ClaimsPrincipal User
{
get
{
return HttpContext?.User;
}
}
und die Steuerung greift die HttpContext
über ControllerContext
/// <summary>
/// Gets the <see cref="Http.HttpContext"/> for the executing action.
/// </summary>
public HttpContext HttpContext
{
get
{
return ControllerContext.HttpContext;
}
}
Sie werden feststellen, dass diese beiden nur Eigenschaften gelesen werden. Die gute Nachricht ist, dass die ControllerContext
Eigenschaft die Einstellung des Wertes erlaubt, so dass Sie Ihren Weg finden.
Also das Ziel ist es, an diesem Objekt zu bekommen. In Core HttpContext
ist abstrakt, so dass es viel einfacher ist zu verspotten.
einen Controller wie
public class MyController : Controller {
IMyContext _context;
public MyController(IMyContext context) {
_context = context;
}
public IActionResult Index() {
SettingsViewModel svm = _context.MySettings(User.Identity.Name);
return View(svm);
}
//...other code removed for brevity
}
Verwendung Moq Angenommen, ein Test wie dieser
public void Given_User_Index_Should_Return_ViewResult_With_Model() {
//Arrange
var username = "FakeUserName";
var identity = new GenericIdentity(username, "");
var mockPrincipal = new Mock<IPrincipal>();
mockPrincipal.Setup(x => x.Identity).Returns(identity);
mockPrincipal.Setup(x => x.IsInRole(It.IsAny<string>())).Returns(true);
var mockHttpContext = new Mock<HttpContext>();
mockHttpContext.Setup(m => m.User).Returns(mockPrincipal.Object);
var model = new SettingsViewModel() {
//...other code removed for brevity
};
var mockContext = new Mock<IMyContext>();
mockContext.Setup(m => m.MySettings(username)).Returns(model);
var controller = new MyController(mockContext.Object) {
ControllerContext = new ControllerContext {
HttpContext = mockHttpContext.Object
}
};
//Act
var viewResult = controller.Index() as ViewResult;
//Assert
Assert.IsNotNull(viewResult);
Assert.IsNotNull(viewResult.Model);
Assert.AreEqual(model, viewResult.Model);
}
In meinem Fall war 'new Claim (ClaimTypes.Name," 1 ")' passend zur Controller-Verwendung von 'user.Identity.Name'; aber ansonsten wollte ich genau das erreichen ... Danke schon! – Felix
Nach unzähligen Stunden Suche war das der Post, der mich endlich zum Quadrat brachte. In meiner Core 2.0-Projekt-Controller-Methode habe ich 'User.FindFirstValue (ClaimTypes.NameIdentifier);' verwendet, um die userId für ein Objekt festzulegen, das ich erstellt habe und fehlgeschlagen ist, weil der Prinzipal null war. Das hat das für mich behoben. Danke für die tolle Antwort! –