Как я могу подделать HttpContext для модульных тестов? - PullRequest
9 голосов
/ 15 августа 2010

Мне нужно подделать таблицу HttpContext.Current.Application, чтобы получить доступ к ней из моих модульных тестов.

Мне нужно где-то хранить свои данные.Я думал, что могу просто передать экземпляр NameValueCollectionBase, но, как я обнаружил, этот базовый тип не имеет индексатора, поэтому он кажется слишком сложным для использования.

Так что насчет подделки этой части HttpContext?Является ли это возможным?Как я могу это сделать?Будет ли NUnit.Mocks полезным?

Заранее спасибо ...

Ответы [ 3 ]

2 голосов
/ 15 августа 2010

Пожалуйста, перейдите по ссылкам ниже, это поможет вам.

http://www.java2s.com/Open-Source/CSharp/Web-Frameworks/MvcContrib/MvcContrib/TestHelper/Fakes/FakeHttpContext.cs.htm

Mocking и HttpContextBase.get_User ()

Спасибо Venkat

1 голос
/ 16 августа 2010

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

public static IEnumerable<KeyValuePair<string, string>> ToPairs(this NameValueCollection collection)
{
    if(collection == null)
    {
        throw new ArgumentNullException("collection");
    }

    return collection.Cast<string>().Select(key => new KeyValuePair<string, string>(key, collection[key]));
}

Чтобы просто хранить данные и передавать методы тестирования, используйте приведенный выше код.

0 голосов
/ 06 сентября 2016

В этом сценарии я генерирую некоторые заглушки, полученные из базовых классов в System.Web.Abstractions. Я часто использую эту технику для приложений MVC, поскольку контроллеры MVC / WebApi содержат абстракцию к HttpContext (HttpContextBase)

Таким образом, я могу заглушить требования HttpContext в моих модульных / интеграционных тестах, вот пример ...

public class MockHttpApplicationState : HttpApplicationStateBase
{
    private IDictionary<string, object> _appState = new Dictionary<string, object>();

    public override void Add(string name, object value)
    {
        _appState.Add(name, value);
    }

    public override object Get(string name)
    {
        return _appState[name];
    }

    public override object this[string name]
    {
        get
        {
            return _appState[name];
        }

        set
        {
            _appState[name] = value;
        }
    }
}

public class MockHttpContext : HttpContextBase
{
    private IDictionary<string, object> _appKeys;

    public MockHttpContext()
    {

    }

    /// <summary>
    /// Accepts a dictionary of app keys to supply to the HttpApplicationState instance
    /// </summary>
    /// <param name="applicationState"></param>
    public MockHttpContext(IDictionary<string,object> applicationState)
    {
        _appKeys = applicationState;
    }

    public override Cache Cache
    {
        get
        {                
            return HttpRuntime.Cache;
        }
    }

    public override HttpApplicationStateBase Application
    {
        get
        {
            var mockAppState = new MockHttpApplicationState();

            foreach (string key in _appKeys.Keys)
            {
                mockAppState.Add(key, _appKeys[key]);
            }

            return mockAppState;
        }
    }

    public override HttpRequestBase Request
    {
        get
        {
            return new HttpRequestWrapper(new HttpRequest(null,"http://localhost",null));
        }
    }
}

Тогда мой тест может установить Контроллер и Http Context:

private readonly OnlineShop.MVC.Controllers.HomeController _controller = 
        new MVC.Controllers.HomeController(null,new UnitOfWork());

    [OneTimeSetUp]
    public void Init()
    {
        var appKeys = new Dictionary<string, object>();

        appKeys.Add("localhost", 1);

        var httpContext = new MockHttpContext(appKeys);

        _controller.ControllerContext = new ControllerContext()
        {
            Controller = _controller,
            RequestContext = new RequestContext(httpContext, new RouteData())    
        };                        
    }

    [Test]
    public void Index_Returns_HomeView()
    {            
        var view = _controller.Index() as ViewResult;
        var viewModel = view.Model as MVC.ViewModels.Home;

        Assert.IsInstanceOf<OnlineShop.MVC.ViewModels.Home>(viewModel);
        Assert.IsTrue(viewModel.FeaturedProducts.Count > 0);
    }

И мой контроллер знает, что его окружающий экземпляр HttpContextBase предоставляет состояние Cache и Application:

  public ActionResult Index()
    {                        
        string cacheKey = string.Format("FeaturedProducts-{0}",WebsiteId);
        IList<Product> productList = this.HttpContext.Cache[cacheKey] as IList<Product>;


        //My app keeps a list of website contexts in the Application. This test returns 1 based on the unit / int tests or a real world db value when hosted on IIS etc..
        int websiteId = (int)HttpContext.Application[this.Request.Url.Host];
...