This is a migrated thread and some comments may be shown as answers.

[Solved] GridRouteValues and testing

4 Answers 42 Views
Grid
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Jess M
Top achievements
Rank 1
Jess M asked on 29 Mar 2012, 04:13 PM
Hello all,

I'm using Grid in multiple views (Index) for each controller I have a unit test class.
I'm using the extension this.GridRouteValues()
I'm using asp net mvc 3.
All the grid in my project are storing the filters and orderby settings of each user.

Since I updated to the new version ( Q1 2012 (version 2012.1.214.0)) all my test for index action raise the following exception:

<b>Test has failed.</b>
Test method FmsWebPortalTest.LocationControllerTest.IndexTest threw exception:
System.NullReferenceException: Object reference not set to an instance of an object.
    at Microsoft.Web.Infrastructure.DynamicValidationHelper.ValidationUtility.CollectionReplacer.GetUnvalidatedCollections(HttpContext context)
   at Microsoft.Web.Infrastructure.DynamicValidationHelper.ValidationUtility.GetUnvalidatedCollections(HttpContext context, Func`1& formGetter, Func`1& queryStringGetter)
   at System.Web.Helpers.Validation.Unvalidated(HttpRequest request)
   at Telerik.Web.Mvc.Extensions.GridControllerExtensions.GetParams(HttpRequestBase request)
   at Telerik.Web.Mvc.Extensions.GridControllerExtensions.GridRouteValues(ControllerBase controller)

this is the code of Index test (all my test are similar):

        [TestMethod()]<br>        public void IndexTest()<br>        {<br>            // Arrange<br>            const string expectedViewName = "Index";<br><br>            // We create a fake repository instance using Rhino.Mocks<br>            ICustomersRepository customerRep = MockRepository.GenerateStub<ICustomersRepository>();<br>            ILocationsRepository locationRep = MockRepository.GenerateStub<ILocationsRepository>();<br>            ILocationContactsRepository locationContactRep = MockRepository.GenerateStub<ILocationContactsRepository>();<br>            IRegionsRepository regionRep = MockRepository.GenerateStub<IRegionsRepository>();<br>            IStatesRepository statesRep = MockRepository.GenerateStub<IStatesRepository>();<br>            IUserPreferenceRepository prefRep = MockRepository.GenerateStub<IUserPreferenceRepository>();<br><br>            IApplicationRepository applicationRep = MockRepository.GenerateStub<IApplicationRepository>();<br>            IUserActivityRepository userActivityrep = MockRepository.GenerateStub<IUserActivityRepository>();<br><br>            using (LocationController target = new LocationController(customerRep, locationRep, locationContactRep, regionRep, statesRep, prefRep, applicationRep, userActivityrep))<br>            {<br>                target.ControllerContext = new ControllerContext(MvcMockHelpers.DynamicHttpContextBase(new MockRepository()), new RouteData(), target);<br>                // Act<br>                var resultView = target.Index(new GridCommand()) as ViewResult;<br>                // Assert   <br>                Assert.AreEqual(expectedViewName, resultView.ViewName, "View name should have been {0}", expectedViewName);<br>                Assert.IsNotNull(resultView.Model);<br>            }<br>        }<br><br>

this is the code of Index (all my index actions are similar, all use this.GridRouteValue):

[GridAction]<br>        [AuthorizeThis(Roles = "Locations Administrator,Locations Reader")]<br>        public ActionResult Index(GridCommand command)<br>        {<br>            // User Preference ------------<br>            GridPreference userGridPreference = UserPreferenceHelper.CheckPreferences(preferencesRepository,applicationRepository, this, this.GridRouteValues());<br><br>            if (UserPreferenceHelper.IsEmptyCommand(command) && (!UserPreferenceHelper.IsEmpty(userGridPreference)))<br>            {   // Load persisted preferences for the current user<br>                RouteValueDictionary routeValues = UserPreferenceHelper.GetRouteValuesForStoredUserPreferences(userGridPreference);<br>                return RedirectToAction(ValueProvider.GetValue("action").RawValue.ToString(), (RouteValueDictionary)routeValues);<br>            }<br><br>            // Get Current Data Filter<br>            DataFilter currentFilter = DataFilterHelper.GetDataFilter(command);<br><br>            // Reference Loader<br>            Ith.Fms2Interfaces.ReferenceLoader referenceLoader = new Ith.Fms2Interfaces.ReferenceLoader { Region = true, Customer = true };<br>            <br>            // View Model<br>            AllLocationsViewModel locations = new AllLocationsViewModel(locationsRepository.GetLocations(currentFilter, referenceLoader)) {<br>                TotalRecords = locationsRepository.TotalLocations, <br>                ActiveFiltersMessage = WebUtils.Filter.GetFilterDescription(currentFilter) <br>            };<br><br>            return View("Index", locations);<br>        }

I suspect that error is because this new piece of code in

GridControllerExtensions.cs

 
<div class="line number41 index40 alt2"></div><div class="line number42 index41 alt1"><code class="csharp preprocessor">#if MVC3</code></div><div class="line number43 index42 alt2"><code class="csharp spaces">        </code><code class="csharp keyword">private</code> <code class="csharp keyword">static</code> <code class="csharp plain">IDictionary<</code><code class="csharp keyword">string</code><code class="csharp plain">, </code><code class="csharp keyword">object</code><code class="csharp plain">> GetParams(HttpRequestBase request)</code></div><div class="line number44 index43 alt1"><code class="csharp spaces">        </code><code class="csharp plain">{</code></div><div class="line number45 index44 alt2"><code class="csharp spaces">            </code><code class="csharp plain">var result = </code><code class="csharp keyword">new</code> <code class="csharp plain">Dictionary<</code><code class="csharp keyword">string</code><code class="csharp plain">, </code><code class="csharp keyword">object</code><code class="csharp plain">>();</code></div><div class="line number46 index45 alt1"><code class="csharp spaces">            </code><code class="csharp plain">var unvalidated = request.Unvalidated();</code></div><div class="line number47 index46 alt2"><code class="csharp spaces">            </code><code class="csharp plain">unvalidated.Form.CopyTo(result);</code></div><div class="line number48 index47 alt1"><code class="csharp spaces">            </code><code class="csharp plain">unvalidated.QueryString.CopyTo(result);</code></div><div class="line number49 index48 alt2"><code class="csharp spaces">            </code><code class="csharp keyword">return</code> <code class="csharp plain">result;</code></div><div class="line number50 index49 alt1"><code class="csharp spaces">        </code><code class="csharp plain">}</code></div><div class="line number51 index50 alt2"><code class="csharp preprocessor">#else</code></div><code class="csharp spaces">      </code>

This is the rhino mock helper that I'm using:

using System;<br>using System.Collections.Specialized;<br>using System.IO;<br>using System.Security.Principal;<br>using System.Web;<br>using Rhino.Mocks;<br><br>namespace FmsWebPortalTest.TestHelpers<br>{<br>    public static class MvcMockHelpers<br>    {<br>        public static HttpContextBase DynamicHttpContextBase(this MockRepository mocks)<br>        {<br>            return mocks.DynamicHttpContextBase<br>                (mocks.DynamicHttpBrowserCapabilitiesBase(),<br>                 mocks.DynamicHttpRequestBase(),<br>                 mocks.DynamicHttpResponseBase(),<br>                 mocks.DynamicHttpSessionStateBase(),<br>                 mocks.DynamicHttpServerUtilityBase(),<br>                 mocks.DynamicIPrincipal());<br>        }<br><br>        public static HttpContextBase DynamicHttpContextBase(this MockRepository mocks, IPrincipal principal,<br>                                                             HttpBrowserCapabilitiesBase browser)<br>        {<br>            return mocks.DynamicHttpContextBase<br>                (browser,<br>                 mocks.DynamicHttpRequestBase(),<br>                 mocks.DynamicHttpResponseBase(),<br>                 mocks.DynamicHttpSessionStateBase(),<br>                 mocks.DynamicHttpServerUtilityBase(),<br>                 principal);<br>        }<br><br>        public static HttpContextBase DynamicHttpContextBase(this MockRepository mocks,<br>                                                             HttpBrowserCapabilitiesBase browser,<br>                                                             HttpRequestBase request,<br>                                                             HttpResponseBase response,<br>                                                             HttpSessionStateBase session,<br>                                                             HttpServerUtilityBase server,<br>                                                             IPrincipal user)<br>        {<br>            var context = mocks.DynamicMock<HttpContextBase>();<br>            SetupResult.For(context.User).Return(user);<br>            SetupResult.For(request.Browser).Return(browser);<br>            SetupResult.For(context.Request).Return(request);<br>            SetupResult.For(context.Response).Return(response);<br>            SetupResult.For(context.Session).Return(session);<br>            SetupResult.For(context.Server).Return(server);<br>            mocks.Replay(context);<br>            return context;<br>        }<br><br>        public static HttpBrowserCapabilitiesBase DynamicHttpBrowserCapabilitiesBase(this MockRepository mocks)<br>        {<br>            var browser = mocks.DynamicMock<HttpBrowserCapabilitiesBase>();<br>            return browser;<br>        }<br><br>        public static HttpRequestBase DynamicHttpRequestBase(this MockRepository mocks)<br>        {<br>            var request = mocks.DynamicMock<HttpRequestBase>();<br>            SetupResult.For(request.Form).Return(new NameValueCollection());<br>            SetupResult.For(request.QueryString).Return(new NameValueCollection());<br>            return request;<br>        }<br><br>        public static HttpResponseBase DynamicHttpResponseBase(this MockRepository mocks)<br>        {<br>            var response = mocks.DynamicMock<HttpResponseBase>();<br>            SetupResult.For(response.OutputStream).Return(new MemoryStream());<br>            SetupResult.For(response.Output).Return(new StringWriter());<br>            SetupResult.For(response.ContentType).PropertyBehavior();<br>            return response;<br>        }<br><br>        public static HttpSessionStateBase DynamicHttpSessionStateBase(this MockRepository mocks)<br>        {<br>            var session = mocks.DynamicMock<HttpSessionStateBase>();<br>            session.Stub(m => m["SipApplicationId"]).Return(new Guid("00000000-0000-0000-0000-000000000001"));<br>            mocks.Replay(session);<br>            <br>            return session;<br>        }<br><br>        public static HttpServerUtilityBase DynamicHttpServerUtilityBase(this MockRepository mocks)<br>        {<br>            var server = mocks.DynamicMock<HttpServerUtilityBase>();<br>            return server;<br>        }<br><br>        public static IPrincipal DynamicIPrincipal(this MockRepository mocks)<br>        {<br>            var principal = mocks.DynamicMock<IPrincipal>();<br>            return principal;<br>        }<br>    }<br>}

My question is

Do you know how I can mock request.unvalidated()?
or ( at System.Web.Helpers.Validation.Unvalidated(HttpRequest request))
Do you know some workaround for this?

This is not urgent, but I would like to fix all the broken test.

Thanks in advance!


4 Answers, 1 is accepted

Sort by
0
Kevin
Top achievements
Rank 1
answered on 11 Jan 2013, 04:03 PM
I realize this is an old issue, but it doesn't have a solution reply and extensive searching hasn't found a solution either.  I'm also getting the NullReferenceException when testing the GridRouteValues method. 

As the original poster indicates, it's failing on a call to HttpRequest Unvalidated method. 

Is there a way to 'mock' this method or is there a workaround?
0
Atanas Korchev
Telerik team
answered on 14 Jan 2013, 08:51 AM
Hi,

 The GridRouteValues implementation can be found in the \Telerik.Web.Mvc\UI\Grid\GridControllerExtensions.cs file. It goes like this:

public static RouteValueDictionary GridRouteValues(this ControllerBase controller)
{           
    var routeValues = new RouteValueDictionary();
 
    var values = GetParams(controller.ControllerContext.HttpContext.Request);           
 
    foreach (string key in values.Keys)
    {
        if (key.EndsWith(GridUrlParameters.CurrentPage, StringComparison.OrdinalIgnoreCase) ||
            key.EndsWith(GridUrlParameters.Filter, StringComparison.OrdinalIgnoreCase) ||
            key.EndsWith(GridUrlParameters.OrderBy, StringComparison.OrdinalIgnoreCase) ||
            key.EndsWith(GridUrlParameters.GroupBy, StringComparison.OrdinalIgnoreCase) ||
            key.EndsWith(GridUrlParameters.PageSize, StringComparison.OrdinalIgnoreCase))
        {
            routeValues[key] = values[key];
        }
    }
 
    return routeValues;
 
private static IDictionary<string, object> GetParams(HttpRequestBase request)
{
    var result = new Dictionary<string, object>();
    var unvalidated = request.Unvalidated();
    unvalidated.Form.CopyTo(result);
    unvalidated.QueryString.CopyTo(result);
    return result;
}

Mocking the ControllerContext, HttpContext and the Request properties should do the trick.

Regards,
Atanas Korchev
the Telerik team
Check out the successor of Telerik MVC Extensions - Kendo UI for ASP.NET MVC - and deem it for new ASP.NET MVC development.
0
Kevin
Top achievements
Rank 1
answered on 14 Jan 2013, 04:28 PM
Thanks for your response.

Mocking out those things is what is causing the problem.  When mocked out, the GridRouteValues.GetParams method is trying to call the HttpRequest Unvalidated method and is getting a NullReferenceException.

 I'm using MvcContrib to do the mocking (but also occurs when I mock them out manually with Rhino Mocks).

I've attached a simple sample solution that demonstrates the problem.  Just run the Index test and you get the NullReferenceException.

Thanks,
Kevin.
0
Atanas Korchev
Telerik team
answered on 15 Jan 2013, 07:11 AM
Hello Kevin,

 Mocking the Unvalidated extension method is beyond the scope of Telerik support services because it is not an API created or maintained by Telerik.
 I recommend checking the implementation using Reflector or other tool. It probably uses HttpContext.Current which is null in during tests. This stackoverflow question shows how to mock that.

Regards,
Atanas Korchev
the Telerik team
Check out the successor of Telerik MVC Extensions - Kendo UI for ASP.NET MVC - and deem it for new ASP.NET MVC development.
Tags
Grid
Asked by
Jess M
Top achievements
Rank 1
Answers by
Kevin
Top achievements
Rank 1
Atanas Korchev
Telerik team
Share this question
or