Чтобы ответить на ваш вопрос, вам необходимо следующее в тесте:
var requestBase = new Mock<HttpRequestBase>();
requestBase.Setup(r => r.ServerVariables)
.Returns(new NameValueCollection { {"HTTP_X_REWRITE_URL", "your url"} });
var httpContext = new Mock<HttpContextBase>();
httpContext.Setup(x => x.Request).Returns(requestBase.Object);
var ctrCtx = new Mock<ControllerContext>();
ctrCtx.Setup(x => x.HttpContext).Returns(httpContext.Object);
demoController.ControllerContext = ctrCtx.Object;
Однако, как @Mark предложил вам не нужно создавать конкретный экземпляр DeviceDetection
внутри ваших действий, вы должны вводить его. Но вместо того, чтобы вводить конкретный экземпляр, лучше обернуть его в интерфейс IDeviceDetector
и ввести эту абстракцию.
даст ряд преимуществ:
- Вашего действие не зависит от реализации
DeviceDetection
Mock<IDeviceDetection>
позволяет поднять исключение на установке, чтобы проверить обработку исключений вашего try-catch
блока.
- Можно утверждать, что
DetectDevice()
метод называется
Еще одно предложение - никогда не использовать try{} catch(Exception ex){}
, вы должны поймать только те исключения, которые вы можете справиться. Поскольку вы не знаете, какой тип исключения может быть брошен и как эффективно его обрабатывать, например, это может быть OutOfMemoryException
. This article может дать вам основные идеи о различных способах обработки исключений в MVC.
UPDATE: Как я вижу, вы используете Unity в качестве контейнера IoC. Unity имеет возможность inject constructor parameters. Так что вам нужно извлечь интерфейс с DeviceDetector
, скажем, IDeviceDetector
. Зарегистрируйте
container.RegisterType<IDeviceDetector, DeviceDetector>(new InjectionConstructor(
HttpContext.Current.Request.ServerVariables["HTTP_X_REWRITE_URL"].ToString()));
регистр DeviceDetector
с TransientLifetimeManager
.
Затем контроллер должен выглядеть
public class DemoController : Controller
{
private readonly ICommonOperationsRepository _commonRepo;
private readonly IDeviceDetection _deviceDetection;
public DemoController (
ICommonOperationsRepository commonRepo,
IDeviceDetection deviceDetection)
{
_commonRepo = commonRepo;
_deviceDetection = deviceDetection;
}
public ActionResult Default()
{
var model = new DemoModel();
_deviceDetection.DetectDevice();
model.ListTopListing.AddRange(_commonRepo.GetListings());
return View(model);
}
}
Примечания, в этом случае вам нужно писать тесты для вашего контейнера Unity, чтобы убедиться, что ваши инъекции решены правильно. Ваш блок-тест может выглядеть так:
[TestMethod]
public void Test()
{
var repository = new Mock<ICommonOperationsRepository>();
var deviceDetection = new Mock<IDeviceDetection>();
var controller = new DemoController(repository.Object, deviceDetection.Object);
controller.Default();
deviceDetection.Verify(x => x.DetectDevice(), Times.Once());
}
Это дает мне полное исключение ссылки, как только я создаю DetectDevice. – maverick
Можете ли вы опубликовать код вашего теста? –
var usedController = new UsedController (новый CommonOperationsRepository()); var requestBase = new Mock(); requestBase.Setup (r => r.ServerVariables) . Возвраты (новое имяValueCollection {{"HTTP_X_REWRITE_URL", "/ used /"}}); var httpContext = new Mock (); httpContext.Setup (x => x.Request). Возвраты (requestBase.Object); –
maverick