Издевательский HttpContext не работает

Я пытаюсь высмеять HttpContext, чтобы я мог unit test мой контроллер Request.IsAuthenicated call. Я использую код который я нашел в блоге Scott Hanselman, чтобы имитировать HttpContext, используя rhino.mocks. поэтому у меня есть этот unit test фрагмент:

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

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

Ответ 1

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

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);

Ответ 4

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

Если вы хотите издеваться над 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
}

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

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

Ответ 5

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

        TextWriter tw = new StringWriter();
        HttpWorkerRequest wr = new SimpleWorkerRequest("/webapp", "c:\\inetpub\\wwwroot\\webapp\\", "default.aspx", "", tw);
        HttpContext.Current = new HttpContext(wr);

Ответ 6

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