Ответ 1
Вы говорите об ASP.NET MVC? Я так думаю.
Вам нужно создать экземпляр контроллера и установить его RequestContext. Вы издеваетесь над HttpContext RequestContext, и внутри этого HttpContext вы издеваетесь над свойством User и настраиваете его на ваш издеваемый IPrincipal:
var principal = new Moq.Mock<IPrincipal>();
// ... mock IPrincipal as you wish
var httpContext = new Moq.Mock<HttpContextBase>();
httpContext.Setup(x => x.User).Returns(principal.Object);
// ... mock other httpContext properties, methods, as needed
var reqContext = new RequestContext(httpContext.Object, new RouteData());
// now create the controller:
var controller = new MyController();
controller.ControllerContext =
new ControllerContext(reqContext, controller);
Надеюсь, что это поможет.
EDIT:
FYI, свойство User в классе Controller происходит из объекта HttpContext, как вы можете видеть здесь (это метод getter для свойства User, полученный из Reflector - вы также можете загрузить исходный код ASP.NET MVC ):
public IPrincipal User
{
get
{
if (this.HttpContext != null)
{
return this.HttpContext.User;
}
return null;
}
}
Если вы теперь проверяете свойство HttpContext, вы увидите:
public HttpContextBase HttpContext
{
get
{
if (base.ControllerContext != null)
{
return base.ControllerContext.HttpContext;
}
return null;
}
}
Итак, все до сих пор было "только для чтения". И нам нужен способ "ввести" насмешливого "Пользователя". Итак, мы проверяем, что мы можем фактически ввести объект ControllerContext в контроллер через свойство. Мы проверяем, как он получает свой объект "HttpContext", чтобы знать, как правильно имитировать:
public virtual HttpContextBase HttpContext
{
get
{
if (this._httpContext == null)
{
this._httpContext = (this._requestContext != null) ? this._requestContext.HttpContext : new EmptyHttpContext();
}
return this._httpContext;
}
set
{
this._httpContext = value;
}
}
Итак, здесь мы видим, что объект ControllerContext получает HttpContext из объекта RequestContext. Это может объяснить, что я сделал выше:
- Откажитесь от IPrincipal с данными, которые вы хотите,
- Откажитесь от HttpContext и передайте его с помощью IPrincipal,
- Выделите RequestContext и передайте его с помощью HttpContext,
- Создайте экземпляр вашего контроллера и установите его свойство ControllerContext для издевающегося объекта RequestContext.
После всего этого волшебства контроллер не будет знать, что вы вызываете его без фактического подключения, которое делается через веб-сервер.
Итак, вы можете продолжать использовать свое свойство "Пользователь" внутри вашего контроллера, как обычно, никаких изменений не должно быть сделано.