Dans les versions précédentes, vous pourriez avoir réglé User
directement sur le contrôleur, qui a fait pour certains très facile de tests unitaires.
Si vous regardez il de code source pour ControllerBase vous remarquerez que l' User
est extrait de l' HttpContext
.
/// <summary>
/// Gets or sets the <see cref="ClaimsPrincipal"/> for user associated with the executing action.
/// </summary>
public ClaimsPrincipal User
{
get
{
return HttpContext?.User;
}
}
et le contrôleur accède à l' HttpContext
par ControllerContext
/// <summary>
/// Gets the <see cref="Http.HttpContext"/> for the executing action.
/// </summary>
public HttpContext HttpContext
{
get
{
return ControllerContext.HttpContext;
}
}
Vous remarquerez que ces deux sont des propriétés en lecture seulement. La bonne nouvelle, c'est qu' ControllerContext
propriété permet le réglage de la valeur, de sorte que ce sera votre façon.
Donc, l'objectif est d'obtenir à cet objet. Le Noyau de l' HttpContext
est abstraite, de sorte qu'il est beaucoup plus facile de se moquer.
En supposant un contrôleur comme
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
}
À l'aide de Moq, un test pourrait ressembler à ceci
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);
}