Обновление: передача HttpContext и IPrincipal в Controler в модульном тесте ReSharper
Я пытаюсь запустить пару базовых модульных тестов на контроллере ASP MVC, однако в какой-то момент контроллер должен проверить IPrincipal
User
объект вроде так:
ViewBag.Level = Security.GetLevel(User);
Как только тестовый модуль входит в Create
Метод контроллера, однако, приведенная выше строка бросает NullReferenceException
как User
объект null
,
Любые идеи о том, как установить IPrincipal
для сеанса юнит-теста?
Вот тест, как я написал прямо сейчас. Я попытался получить доступ к User
объект и просто установить его, прежде чем тест переходит в Create
метод, однако intellisense не поднимает его.
[Test]
public void a06_CloneFromDatabase()
{
using (AgentResources db = new AgentResources())
{
var master = (from a in db.AgentTransmission
where a.RecordStatus.Equals("C")
select a).FirstOrDefault();
var result = _controlAgtTran.Create(master.ID, null, string.Empty, string.Empty, string.Empty, string.Empty, false) as ViewResult;
var model = result.Model as AgentTransmission;
Assert.AreEqual(model.ReferenceType, master.ReferenceType);
}
}
РЕДАКТИРОВАТЬ
После поста, упомянутого в комментариях ниже, я нашел способ создать HttpContext
сеанс и применить и IPrincipal
на эту сессию. Это работает нормально, пока тестовый модуль не переместится в контроллер, где HttpContext
а также IPrincipal
User
все объекты, опять же, нулевые.
Так как кажется, что экземпляр контроллера, который я использую, имеет HttpContext
свойство только для чтения (и IPrincipal
User
собственность) знает ли кто-нибудь способ прохождения HttpContext
используется в модульном тестировании внутри тестируемого контроллера? Кроме того, если это невозможно, какой метод тестирования можно использовать? RouteValues
используя юнит-тесты РеШарпера?
[SetUp]
public void SetUp()
{
_controlAgtTran = new AgentTransmissionController();
/****Set up Current HTTP Context to pass Security.cs checks*****/
//Set up the HTTP Request
var httpRequest = new HttpRequest("", "http://localhost:2574/", "");
//Set up the HTTP Response
var httpResponse = new HttpResponse(new StringWriter());
//Set up the HTTP Context
var httpContext = new HttpContext(httpRequest, httpResponse);
var sessionContainer = new HttpSessionStateContainer("NEAROD",
new SessionStateItemCollection(),
new HttpStaticObjectsCollection(),
100,
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});
//Assign the context
HttpContext.Current = httpContext;
}
[Test]
public void a01_IncompleteRecordGoesToEdit()
{
AgentTransmission agtTran = new AgentTransmission();
agtTran.ReferenceNumber = 95820518787;
agtTran.ReferenceType = "S";
agtTran.EffectiveDate = DateTime.Now;
agtTran.RelationshipEffDate = DateTime.Now;
agtTran.RecordStatus = "N";
agtTran.CreatedDate = DateTime.Now;
agtTran.CreatedOperator = "xTest1";
agtTran.FirstName = "Unit";
agtTran.LastName = "Test";
agtTran.ExtRepType = "EXTREPID";
agtTran.JIT = true;
agtTran.SendToDRM = true;
agtTran.SendToNMF = true;
agtTran.WelcomeLetter = true;
agtTran.OverrideRegionInd = false;
//set IPrincipal
string[] roles = {"LCO"};
IPrincipal principal = new GenericPrincipal(new GenericIdentity("SYMETRA\\NEAROD"), roles);
HttpContext.Current.User = principal;
IPrincipal user = HttpContext.Current.User;
Assert.AreEqual(user, principal); //This passes
Assert.AreEqual(principal, _controlAgtTran.User); //this fails
var result = (RedirectToRouteResult)_controlAgtTran.Create(agtTran); //this crashes
//Tests aren't run
Assert.IsNotNull(result);
Assert.AreEqual(3, result.RouteValues.Count);
Assert.AreEqual("AgentTransmission", result.RouteValues["controller"]);
Assert.AreEqual("Edit", result.RouteValues["action"]);
}
1 ответ
Следуя аналогичному решению, упомянутому в этом посте, я добавил следующее в конец SetUp()
метод.
var controllerCtx = new ControllerContext();
controllerCtx.HttpContext = new HttpContextWrapper(HttpContext.Current);
_controlAgtTran.ControllerContext = controllerCtx;
Обтекание тока HttpContext
внутри HttpContextBase
собственность (неправильно названная controllerCtx.HttpContext
) тест теперь имеет доступ к User
а также HttpContext
свойства контроллера. Эти свойства ранее были доступны только для чтения при использовании только HttpContext.Current
сеанс и, следовательно, всегда ноль.
К вашему сведению - это мое первое модульное тестирование с этими объектами, поэтому объяснение может быть менее чем на 100% правильным. Пожалуйста, не стесняйтесь комментировать ниже, и я сделаю все необходимые изменения.