Я прочитал некоторые ответы здесь: тестирование представлений и контроллеров и насмешливость, но я до сих пор не могу понять, как тестировать контроллер ASP.NET MVC, который читает и устанавливает значения Session (или любые другие переменные на основе контекста .) Как предоставить (сеанс) контекст для моих методов тестирования? Издевается над нами? У кого-нибудь есть примеры? В принципе, я хотел бы подделать сеанс, прежде чем я вызову метод контроллера, и контроллер будет использовать этот сеанс. Есть идеи?ASP/NET MVC: Контрольные контроллеры с сеансами? Дразнящий?
ответ
Заканчивать пост Стивена Walther на Подделка контекста контроллера:
ASP.NET MVC Tip #12 – Faking the Controller Context
[TestMethod]
public void TestSessionState()
{
// Create controller
var controller = new HomeController();
// Create fake Controller Context
var sessionItems = new SessionStateItemCollection();
sessionItems["item1"] = "wow!";
controller.ControllerContext = new FakeControllerContext(controller, sessionItems);
var result = controller.TestSession() as ViewResult;
// Assert
Assert.AreEqual("wow!", result.ViewData["item1"]);
// Assert
Assert.AreEqual("cool!", controller.HttpContext.Session["item2"]);
}
Структура ASP.NET MVC не очень проста в обращении (или, скорее, требует слишком много настроек для правильной настройки и вызывает слишком много трения при тестировании, IMHO) из-за использования абстрактных базовых классов вместо интерфейсов. Нам удавалось писать абстракции для каждого запроса и сеансового хранилища. Мы сохраняем эти абстракции очень легкими, а затем наши контроллеры зависят от этих абстракций для каждого запроса или для хранения в сеансе.
Например, вот как мы управляем файлами auth. У нас есть ISecurityContext:
public interface ISecurityContext
{
bool IsAuthenticated { get; }
IIdentity CurrentIdentity { get; }
IPrincipal CurrentUser { get; set; }
}
С конкретной реализации, как:
public class SecurityContext : ISecurityContext
{
private readonly HttpContext _context;
public SecurityContext()
{
_context = HttpContext.Current;
}
public bool IsAuthenticated
{
get { return _context.Request.IsAuthenticated; }
}
public IIdentity CurrentIdentity
{
get { return _context.User.Identity; }
}
public IPrincipal CurrentUser
{
get { return _context.User; }
set { _context.User = value; }
}
}
Скотт Hanselman имеет пост о том, как create a file upload quickapp с MVC и обсуждает moking и конкретно касается «Как издеваются вещи, которые Арен «дружище».
Я нашел насмешливым, чтобы быть довольно простым. Вот пример издевательства над httpContextbase (содержащий объекты запроса, сеанса и ответа) с помощью moq.
[TestMethod]
public void HowTo_CheckSession_With_TennisApp() {
var request = new Mock<HttpRequestBase>();
request.Expect(r => r.HttpMethod).Returns("GET");
var httpContext = new Mock<HttpContextBase>();
var session = new Mock<HttpSessionStateBase>();
httpContext.Expect(c => c.Request).Returns(request.Object);
httpContext.Expect(c => c.Session).Returns(session.Object);
session.Expect(c => c.Add("test", "something here"));
var playerController = new NewPlayerSignupController();
memberController.ControllerContext = new ControllerContext(new RequestContext(httpContext.Object, new RouteData()), playerController);
session.VerifyAll(); // function is trying to add the desired item to the session in the constructor
//TODO: Add Assertions
}
Надеюсь, что это поможет.
Ого, это много работы, чтобы издеваться один метод :) Это явно «слишком много настроек «запах, и это результат использования абстрактных базовых классов, а не интерфейсов в качестве швов зависимостей. – chadmyers 2008-10-06 23:18:49
Несомненно, я видел несколько проектов, в которых они установили код установки в класс «помощник» и использовали его снова и снова. – Korbin 2008-10-07 22:24:51
С MVC RC 1 ControllerContext обертывания HttpContext и выставляет его как свойство. Это делает насмешливым намного легче. Для того, чтобы издеваться переменным сеанс с Moq выполните следующие действия:
var controller = new HomeController();
var context = MockRepository.GenerateStub<ControllerContext>();
context.Expect(x => x.HttpContext.Session["MyKey"]).Return("MyValue");
controller.ControllerContext = context;
См Scott Gu's post для более подробной информации.
Поскольку HttpContext является статическим, я использую Typemock Isolator, чтобы издеваться над ним, Typemock также имеет надстройку, созданную для ASP.NET unit testing, называемую Ivonna.
Я использовал следующее решение - создание контроллера, из которого наследуются все мои другие контроллеры.
public class TestableController : Controller
{
public new HttpSessionStateBase Session
{
get
{
if (session == null)
{
session = base.Session ?? new CustomSession();
}
return session;
}
}
private HttpSessionStateBase session;
public class CustomSession : HttpSessionStateBase
{
private readonly Dictionary<string, object> dictionary;
public CustomSession()
{
dictionary = new Dictionary<string, object>();
}
public override object this[string name]
{
get
{
if (dictionary.ContainsKey(name))
{
return dictionary[name];
} else
{
return null;
}
}
set
{
if (!dictionary.ContainsKey(name))
{
dictionary.Add(name, value);
}
else
{
dictionary[name] = value;
}
}
}
//TODO: implement other methods here as needed to forefil the needs of the Session object. the above implementation was fine for my needs.
}
}
Затем используйте код следующим образом:
public class MyController : TestableController { }
- 1. Контрольные контроллеры Symfony3
- 2. Контрольные контроллеры = интеграционный тест?
- 3. Контрольные контроллеры проверки --iPhone
- 4. Тест Spring mvc - контрольные контроллеры с автообновленными аннотациями
- 5. Контрольные контроллеры в Play Framework
- 6. Контрольные контроллеры в драгоценных камнях с RSpec
- 7. Имеет ли смысл модульные контрольные контроллеры
- 8. MVC 3: Контрольные контрольные тесты VS интеграционные тесты
- 9. Контрольные контроллеры просмотра в раскадровках в RubyMotion
- 10. iOS: Контрольные контроллеры не освобождаются при отклонении
- 11. Как модульные контрольные контроллеры, которые используют SpringSecurityService?
- 12. WF и ASPNET MVC
- 13. Контроллеры MVC
- 14. Контрольные контроллеры Spring: вызовите методы обслуживания или результаты макета
- 15. Контрольные контроллеры в Rails 3 с Devise и RSpec
- 16. AspNet Mvc автоматически выбирает ConnectionString
- 17. aspnet core dnx MVC Scaffolding
- 18. Регистрация IWindsorContainer с ASPNET MVC 2.0 Области
- 19. ADFSv2.1 с aspnet mvc 5 redirect loop
- 20. ASPNET MVC RenderAction с параметрами javascript
- 21. ajax с aspnet mvc никогда не работает
- 22. Задачи маршрутизации Aspnet MVC 4
- 23. Fat ASP.NET MVC-контроллеры
- 24. Контрольные рельсовые контроллеры, которые не входят в спецификации/контроллеры с rspec 2
- 25. Контроллеры маршрутизации asp.net mvc
- 26. MVC контроллеры DataContext
- 27. MVC-контроллеры Что делать
- 28. Модульные тесты Контроллеры MVC
- 29. Асинхронные контроллеры MVC
- 30. ASP.NET MVC: Структурирующие контроллеры
Хансельман на помощь ... – Codewerks 2008-10-07 01:37:04