Как протестировать фильтры действий в ASP.NET MVC? - PullRequest
14 голосов
/ 29 июня 2009

Нужны некоторые указатели для этого. Нашел это и это , но я все еще в замешательстве.

Я просто хочу смоделировать ActionExecutedContext, передать его, дать фильтру немного поработать и проверить результат.

Любая помощь?

Источник фильтра вы можете найти здесь
(он немного изменился, но сейчас это не главное).

Итак, я хочу модульный тест, чтобы фильтр RememberUrl был достаточно умен, чтобы сохранять текущий URL в сеансе.

Ответы [ 2 ]

11 голосов
/ 29 июня 2009

1) Mocking Request.Url в ActionExecutedContext:

var request = new Mock<HttpRequestBase>();
request.SetupGet(r => r.HttpMethod).Returns("GET");
request.SetupGet(r => r.Url).Returns(new Uri("http://somesite/action"));

var httpContext = new Mock<HttpContextBase>();
httpContext.SetupGet(c => c.Request).Returns(request.Object);

var actionExecutedContext = new Mock<ActionExecutedContext>();
actionExecutedContext.SetupGet(c => c.HttpContext).Returns(httpContext.Object);

2) Предположим, вы вводите оболочку сеанса в открытый конструктор RememberUrlAttribute.

var rememberUrl = new RememberUrlAttribute(yourSessionWrapper);

rememberUrl.OnActionExecuted(actionExecutedContext.Object);

// Then check what is in your SessionWrapper
3 голосов
/ 30 июня 2009

Это результат:

#region usages

using System;
using System.Collections.Specialized;
using System.Web;
using System.Web.Mvc;
using x.TestBase;
using x.UI.y.Infrastructure.Enums;
using x.UI.y.Infrastructure.Filters;
using x.UI.y.Test.Mocks;
using Moq;

//considering switch to NUnit... :D
using Microsoft.VisualStudio.TestTools.UnitTesting;

#endregion

namespace x.UI.y.Test.Unit.Infrastructure.Filters
{
    [TestClass]
    public class RememberUrlTester : TesterBase
    {
        private static HttpContextBaseMock _context = 
            new HttpContextBaseMock();
        private static ActionExecutedContextMock _actionContext = 
            new ActionExecutedContextMock(_context.Object);

        [TestMethod]
        //"Can save url in session" (i prefer test names in my own language :)
        public void SpeejPieglabaatUrlSesijaa()
        {
            //Arrange
            const string _url = "http://www.foo.bar/foo?bar=bar";
            _context.RequestMock.SetUrl(_url);    
            var filter = new RememberUrlAttribute();

            //Act
            filter.OnActionExecuted(_actionContext.Object);

            //Assert
            _context.SessionMock.Verify
                (m => m.Add(SessionKey.PreviousUrl.ToString(), _url));
        }
    }
}

Обернутый макет для поддержания чистоты тестов.

Я уверен, что все можно сделать лучше, но я думаю, что это отличное начало, и я очень взволнован.

Наконец, этот монстр HttpContext находится под контролем! ^^

...