Перемешивание HttpContext не работает - PullRequest
10 голосов
/ 27 октября 2008

Я пытаюсь смоделировать HttpContext, чтобы я мог модульно протестировать вызов Request.IsAuthenicated моего контроллера. Я использую код , который я нашел в блоге Скотта Хансельмана , для имитации HttpContext с помощью rhino.mocks. так что у меня есть этот блок тестовый образец:

PostsController postsController = new PostsController(postDL);
mocks.SetFakeControllerContext(postsController);
Expect.Call(postsController.Request.IsAuthenticated).Return(true);

В моем действии контроллера у меня есть что-то вроде if(Request.IsAuthenticated).... когда я пытаюсь запустить модульный тест, тест завершается ошибкой, и при попытке отладки модульного теста я вижу, что HttpContext никогда не назначается контроллеру. есть идеи?

Ответы [ 6 ]

8 голосов
/ 27 октября 2008

Это должно работать:

PostsController postsController = new PostsController(postDL);
var context = mocks.Stub<HttpContextBase>();
var request = mocks.Stub<HttpRequestBase>();
SetupResult.For(request.IsAuthenticated).Return(true);
SetupResult.For(context.Request).Return(request);    
postsController.ControllerContext = new ControllerContext(context, new RouteData(), postsController);
2 голосов
/ 27 октября 2008

Это может быть полезным для вас, сработало для меня в похожем сценарии:

http://haacked.com/archive/2007/06/19/unit-tests-web-code-without-a-web-server-using-httpsimulator.aspx

1 голос
/ 12 ноября 2008

Вы можете найти пост, который я написал об этом, чтобы быть полезным в некотором роде http://santoshbenjamin.wordpress.com/2008/08/04/mock-httpcontext-and-session-state/

веселит Бенджи

0 голосов
/ 27 июня 2012

Вот класс, который может быть полезен. Он обрабатывает запросы AJAX, аутентификацию пользователя, параметры запроса и многое другое: https://gist.github.com/3004119

0 голосов
/ 21 сентября 2011

Вот один простой способ подделать контекст, найденный в блоге Джеффа :

        TextWriter tw = new StringWriter();
        HttpWorkerRequest wr = new SimpleWorkerRequest("/webapp", "c:\\inetpub\\wwwroot\\webapp\\", "default.aspx", "", tw);
        HttpContext.Current = new HttpContext(wr);
0 голосов
/ 27 октября 2008

Теперь, для раскрытия информации, мне еще предстоит испачкать руки большинством вещей, с которыми вы работаете, однако:

Если вы хотите издеваться над IsAuthenticated, почему бы просто не создать статический класс для возврата bool, которым может манипулировать ваш тестовый код?

Это немного грубо по краям, но, надеюсь, вы поняли:

interface IAuthenticationChecker
{
    bool IsAuthenticated { get; }
}

public class MockAuthenticationChecker : IAuthenticationChecker
{
    static bool _authenticated = false;

    public static void SetAuthenticated(bool value)
    {
        _authenticated = value;
    }
    #region IAuthenticationChecker Members

    public bool IsAuthenticated
    {
        get { return _authenticated; }
    }

    #endregion
}

public class RequestAuthenticationChecker : IAuthenticationChecker
{

    #region IAuthenticationChecker Members

    public bool IsAuthenticated
    {
        get {
            if (HttpContext.Current == null)
                throw new ApplicationException(
                    "Unable to Retrieve IsAuthenticated for Request becuse there is no current HttpContext.");

            return HttpContext.Current.Request.IsAuthenticated;
        }
    }

    #endregion
}

Затем вы можете использовать ссылку на любой из них на уровне приложения, да, это означает, что вам нужно добавить ссылку на уровне приложения, и вам нужно использовать другую ссылку, а не Запрос, но вы также получаете полный контроль над аутентификацией для тестирование:)

К вашему сведению - это полностью открыто для того, чтобы быть разорванным на части, я бросил это вместе примерно через минуту:)

...