Operation could destabilize the runtime when mocking UrlHelper on MVC3

8 posts, 0 answers
  1. Paul
    Paul avatar
    3 posts
    Member since:
    Mar 2008

    Posted 06 May 2011 Link to this post

    Hi

    I'm trying to unit test an ExecuteResult() method of a custom ActionResult. The method uses UrlHelper.GenerateUrl() method to generate the url for given action and controller.
    Url = UrlHelper.GenerateUrl(null, Action, Controller, new RouteValueDictionary(RouteValues), RouteTable.Routes, context.RequestContext, true);
    In the unit test I'm constructing the ControllerContext like such:
    var request = Mock.Create<HttpRequestBase>();
    var httpContext = Mock.Create<HttpContextBase>();
    Mock.Arrange(() => httpContext.Request).Returns(request);
    var controllerContext = new ControllerContext(httpContext, new RouteData(), new TestDummyController());
    And then setting static mock for the UrlHelper:
    Mock.SetupStatic<UrlHelper>(Behavior.CallOriginal);
    When the runtime hots the GenerateUrl method I'm getting the System.Security.VerificationException "Operation could destabilize the runtime.". The stack trace is not very helpful:
    at System.Web.Mvc.UrlHelper.GenerateUrl(String routeName, String actionName, String controllerName, RouteValueDictionary routeValues, RouteCollection routeCollection, RequestContext requestContext, Boolean includeImplicitMvcValues)
    at Symantec.Web.Mvc.JavaScriptRedirectResult.ExecuteResult(ControllerContext context) in D:\Code\_wsfederation\Applications\IdentityHub\Symantec.Web.Mvc\JavaScriptRedirectResult.cs:line 59
    at Symantec.Web.Mvc.Tests.JavaScriptRedirectResultTest.ExecuteResult_Redirecs_To_Action() in D:\Code\_wsfederation\Applications\IdentityHub\Symantec.Web.Mvc.Tests\JavaScriptRedirectResultTest.cs:line 109

    The GenerateUrl() method works fine when I remove static mock declaration but that makes the whole test pointless. Any help please?
  2. Ricky
    Admin
    Ricky avatar
    467 posts

    Posted 11 May 2011 Link to this post

    Hi Jimmy,
    Thanks again for sending the issue. To isolate the problem, I created a MVC2 project from default template and then wrote this following test :

    Mock.Arrange(() => UrlHelper.GenerateUrl(null, "Home", "Index", null, RouteTable.Routes, null, true)).IgnoreArguments().Returns("/");
    Assert.AreEqual(UrlHelper.GenerateUrl(null, "Home", "Index", null, RouteTable.Routes, null, true), "/");

    The test seems to pass as expected. Therefore, it could be the reason that you are using some other tool that is injecting dynamic code which is actually throwing the exception.

    In addition, please check that you are using the latest release.


    Kind regards,
    Ricky
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  3. DevCraft R3 2016 release webinar banner
  4. Josh
    Josh avatar
    6 posts
    Member since:
    Apr 2012

    Posted 11 Apr 2012 Link to this post

    We're trying out JustMock and are having issues with MVC4 and ASP.NET 4.  I get the same exception that Jimmy was getting.

    Thanks, josh
  5. Ricky
    Admin
    Ricky avatar
    467 posts

    Posted 13 Apr 2012 Link to this post

    Hi Josh,

    Thanks again for reporting the issue.

    I would request you to send me the particular sample you are working on and also please make sure that full .net framework is selected for the test project. It’s a conflict with .net framework 4.0 client profile and Telerik.CodeWeaver.Hook.dll.



    Kind Regards
    Ricky 
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

  6. Josh
    Josh avatar
    6 posts
    Member since:
    Apr 2012

    Posted 13 Apr 2012 Link to this post

    Sure, I've basically just made an empty MVC3 project with an AccountController

    public bool UnitTest(string host)
    {
        if (Url.IsLocalUrl(host))
        {
            return true;
        }
        else
        {
            return false;
        }
    }
     And my unit test here:
    [TestMethod()]
    public void TestUnitTest()
    {
        AccountController target = new AccountController();
        var req_ctx = Mock.Create<RequestContext>();
        var url = Mock.Create<UrlHelper>(req_ctx);
        string host = "http://localhost:50135";
        Mock.Arrange(() => url.IsLocalUrl(Arg.AnyString)).Returns(true);
        target.Url = url;
        bool expected = true; // TODO: Initialize to an appropriate value
        bool actual;
        actual = target.UnitTest(host);
        Assert.AreEqual(expected, actual);
        Assert.Inconclusive("Verify the correctness of this test method.");
    }

    Again, this our teams first attempt at mocking with a web application.  IT looks like UrlHelper could have several dependencies to set, i.e., HttpContextBase, RequestContext, etc.

    Any suggestions are appreciated.
  7. Ricky
    Admin
    Ricky avatar
    467 posts

    Posted 16 Apr 2012 Link to this post

    Hi Josh,
    Thanks again for reporting the issue.

    So far, the exception is due to the loading of assembly that is either internal to the UrlHelper class or is not intercepted properly by JM profiler.  We will investigate further on the issue.

    In the meantime, i wrote your test in the following way that made it work as expected:

    AccountController target = new AccountController();
     
    var req_ctx = Mock.Create<RequestContext>();
     
    var context = Mock.Create<HttpContextBase>();
    var request = Mock.Create<HttpRequestBase>();
     
    string host = "http://localhost:50135";
     
    Mock.Arrange(() => request.Url).Returns(new Uri(host));
     
    Mock.Arrange(() => context.Request).Returns(request);
     
    Mock.Arrange(() => req_ctx.HttpContext).Returns(context);
     
    var url = new UrlHelper(req_ctx);
     
    target.Url = url;
     
    bool expected = true; // TODO: Initialize to an appropriate value
     
    bool actual;
     
    actual = target.UnitTest(host);
     
    Assert.AreEqual(expected, actual);

    Sorry for the inconvenience.

    Kind Regards
    Ricky
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

  8. Real
    Real avatar
    1 posts
    Member since:
    Oct 2011

    Posted 01 Oct 2012 Link to this post

    Hi,

    I have a very similar issue.  This is my first time with JustMock and I am trying to create a series of mocks for Testing ASP.NET MVC 4 helpers.  I have created the following:

            private static ControllerBase GetMockController()
            {
                ControllerBase controller = Mock.Create<ControllerBase>(Behavior.CallOriginal);
                controller.TempData = new TempDataDictionary();
                controller.ViewData = new ViewDataDictionary();
                Mock.Arrange(() => controller.ValueProvider).Returns(Mock.Create<IValueProvider>());
                return controller;
            }

    So as to set, in the mocked object, a pair of dictionaries that will be able to behave the way the original object would.  I got that same error mentioned above when trying to set the first dictionary..  More to the point:

    Test method Utilicase.EPSM.Client.Tests.HtmlHelpers.GenericTools.HelperFactoryParms threw exception:
    System.Security.VerificationException: Operation could destabilize the runtime.

    I thought that maybe it did not like setting objects, so I set null into it and the same error came up.

    What am I doing wrong?
  9. Ricky
    Admin
    Ricky avatar
    467 posts

    Posted 04 Oct 2012 Link to this post

    Hi Forte,

    Thanks again for contacting us. We however noticed the issue and will keep you posted on any update regarding it.
     

    Kind Regards
    Ricky
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

Back to Top
DevCraft R3 2016 release webinar banner