In früheren Versionen haben Sie möglicherweise User
direkt auf dem Controller eingestellt, was einige sehr einfache Komponententests ermöglichte.
Wenn Sie sich den Quellcode für ControllerBase ansehen, werden Sie feststellen, dass der aus User
extrahiert wird HttpContext
.
/// <summary>
/// Gets the <see cref="ClaimsPrincipal"/> for user associated with the executing action.
/// </summary>
public ClaimsPrincipal User => HttpContext?.User;
und die Steuerung greift auf die HttpContext
Via zuControllerContext
/// <summary>
/// Gets the <see cref="Http.HttpContext"/> for the executing action.
/// </summary>
public HttpContext HttpContext => ControllerContext.HttpContext;
Sie werden feststellen, dass diese beiden Eigenschaften schreibgeschützt sind. Die gute Nachricht ist, dass die ControllerContext
Eigenschaft es ermöglicht, ihren Wert so einzustellen, dass Sie sich darauf einlassen.
Das Ziel ist es also, an dieses Objekt zu gelangen. In Core HttpContext
ist abstrakt, so ist es viel einfacher zu verspotten.
Angenommen, ein 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
}
Mit Moq könnte ein Test so aussehen
public void Given_User_Index_Should_Return_ViewResult_With_Model() {
//Arrange
var username = "FakeUserName";
var identity = new GenericIdentity(username, "");
var mockPrincipal = new Mock<ClaimsPrincipal>();
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);
}
new Claim(ClaimTypes.Name, "1")
, Controller Verwendung von anzupassenuser.Identity.Name
; aber sonst ist es genau das, was ich erreichen wollte ... Danke schon!