테스트중인 내 컨트롤러의 세션에 값을 저장하고 있습니다. 세션을 조롱하는 방법에 대한 여러 기사를 읽었으며 Milox의 답변을 Setting the httpcontext current session in unit test에 구현하려고합니다. 그러나 Locals | this | base | HttpContext
Sessions
으로 드릴링 할 때 세션 변수를 설정할 때 Null 참조 예외로 테스트가 실패합니다. HttpContext.Session["BsAcId"] = vM.BusAcnt.Id;
MVC 5에서 조롱 세션이 작동하지 않습니다.
이것이 작업 코드입니다. vM.BusAcnt.Id
이 유효한 int
을 반환하고 int
값으로 대체하면 Session
이 null이므로 테스트가 실패하므로 값을 저장할 수 없습니다.
MVC5, EF6 및 최신 버전의 xUnit, Moq 및 Resharper 테스트 러너를 사용하고 있습니다.
작업 :
public ActionResult Details(int id)
{
var vM = new BusAcntVm();
vM.BusAcnt = _db.BusAcnts.FirstOrDefault(bA => bA.Id == id);
if ((User.IsInRole("Admin"))) return RedirectToAction("Action");
HttpContext.Session["BsAcId"] = vM.BusAcnt.Id;
return View(vM);
}
MockHelpers :
public static class MockHelpers
{
public static HttpContext FakeHttpContext()
{
var httpRequest = new HttpRequest("", "http://localhost/", "");
var stringWriter = new StringWriter();
var httpResponce = new HttpResponse(stringWriter);
var httpContext = new HttpContext(httpRequest, httpResponce);
var sessionContainer = new HttpSessionStateContainer("id", new SessionStateItemCollection(),
new HttpStaticObjectsCollection(), 10, true,
HttpCookieMode.AutoDetect,
SessionStateMode.InProc, false);
httpContext.Items["AspSession"] = typeof(HttpSessionState).GetConstructor(
BindingFlags.NonPublic | BindingFlags.Instance,
null, CallingConventions.Standard,
new[] { typeof(HttpSessionStateContainer) },
null)
.Invoke(new object[] { sessionContainer });
return httpContext;
}
}
테스트 :
[Fact]
public void AdminGetBusAcntById()
{
HttpContext.Current = MockHelpers.FakeHttpContext();
var mockMyDb = MockDbSetup.MockMyDb();
var controller = new BusAcntController(mockMy.Object);
var controllerContextMock = new Mock<ControllerContext>();
controllerContextMock.Setup(x => x.HttpContext.User.
IsInRole(It.Is<string>(s => s.Equals("Admin")))).Returns(true);
controller.ControllerContext = controllerContextMock.Object;
var viewResult = controller.Details(1) as ViewResult;
var model = viewResult.Model as BusAcntVm;
Assert.NotNull(model);
Assert.Equal("Company 1", model.CmpnyName);
}
Milox의 코드를 이해하는 것 같다하지만이 동작하지 않습니다. 내가 놓친 것이 있습니까? 이 코드를 위반하는 MVC5의 변경 사항이 있습니까?
해결책 : 대린의 답변
구현. 이제는 값을 쓰는 세션이 있습니다 (값은 실제로 쓰여지지 않지만 테스트 목적에는 필요하지 않습니다). 테스트가 통과됩니다.
테스트 : 당신의 단위 테스트에서
[Fact]
public void AdminGetBusAcntById()
{
var mockMyDb = MockDbSetup.MockMyDb();
var controller = new BusAcntController(mockMy.Object);
var context = new Mock<HttpContextBase>();
var session = new Mock<HttpSessionStateBase>();
var user = new GenericPrincipal(new GenericIdentity("fakeUser"), new[] { "Admin" });
context.Setup(x => x.User).Returns(user);
context.Setup(x => x.Session).Returns(session.Object);
var requestContext = new RequestContext(context.Object, new RouteData());
controller.ControllerContext = new ControllerContext(requestContext, controller);
var viewResult = controller.Details(1) as ViewResult;
var model = viewResult.Model as BusAcntVm;
Assert.NotNull(model);
Assert.Equal("Company 1", model.CmpnyName);
}
감사합니다. 너는 언제나처럼 그것을 못 박았 다. 내 테스트에서 구현을위한 OP : 해결 방법을 참조하십시오. – Joe
안녕하세요 대린, 당신은 'ASP.NET MVC에서 HttpContext.Current를 잊어 버렸습니다.'라고 말하면서, 예를 들어 컨트롤러 외부의 사용자 정의 클래스에서 Session 객체에 어떻게 액세스 할 수 있습니까? 예를 들어 컨트롤러의 외부에서는 무엇이 이에 해당 하는가? HttpContext.Current.Session [ "MyField"] – Anthony