ในเวอร์ชันก่อนหน้านี้คุณสามารถตั้งค่าUser
ได้โดยตรงบนคอนโทรลเลอร์ซึ่งทำขึ้นเพื่อการทดสอบหน่วยที่ง่ายมาก
หากคุณดูซอร์สโค้ดสำหรับControllerBaseคุณจะสังเกตเห็นว่าUser
แยกมาจากHttpContext
ไฟล์.
public ClaimsPrincipal User => HttpContext?.User;
และคอนโทรลเลอร์จะเข้าถึงHttpContext
ผ่านControllerContext
public HttpContext HttpContext => ControllerContext.HttpContext;
คุณจะสังเกตเห็นว่าทั้งสองเป็นคุณสมบัติอ่านอย่างเดียว ข่าวดีก็คือControllerContext
คุณสมบัติช่วยให้สามารถกำหนดมูลค่าได้เพื่อที่จะเป็นทางเข้าของคุณ
ดังนั้นเป้าหมายคือการไปที่วัตถุนั้น ใน Core HttpContext
เป็นนามธรรมดังนั้นจึงง่ายต่อการเยาะเย้ยมาก
สมมติว่าตัวควบคุมเช่น
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);
}
}
การใช้ Moq การทดสอบอาจมีลักษณะเช่นนี้
public void Given_User_Index_Should_Return_ViewResult_With_Model() {
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() {
};
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
}
};
var viewResult = controller.Index() as ViewResult;
Assert.IsNotNull(viewResult);
Assert.IsNotNull(viewResult.Model);
Assert.AreEqual(model, viewResult.Model);
}
new Claim(ClaimTypes.Name, "1")
จะตรงกับการใช้คอนโทรลเลอร์ของuser.Identity.Name
; แต่อย่างอื่นมันคือสิ่งที่ฉันพยายามจะบรรลุ ... Danke schon!