ilivewithian
ilivewithian

Reputation: 19702

Unit Testing Code that calls VirtualPathUtility.ToAbsolute

I'm trying to unit test some code that calls into VirtualPathUtility.ToAbsolute.

Is this possible with the unit testing tools provided with VS 2008? If not, is it possible with a later version of Visual Studio?

Upvotes: 13

Views: 2900

Answers (3)

Jon Kerr
Jon Kerr

Reputation: 303

We're well past VS 2008 but for anyone who is still grappling with this issue, I've found a solution on: http://forums.asp.net/t/995143.aspx?Mocking+HTTPContext+object.

Use the following code in your test init to override the default AppDomain values. (The VirutalPathUtility static methods will use your new values.)

[TestInitialize]
public void Initialize()
{
    // Fake out env for VirtualPathUtility.ToAbsolute(..)
    string path = AppDomain.CurrentDomain.BaseDirectory; 
    const string virtualDir = "/";
    AppDomain.CurrentDomain.SetData(".appDomain", "*");
    AppDomain.CurrentDomain.SetData(".appPath", path);
    AppDomain.CurrentDomain.SetData(".appVPath", virtualDir);
    AppDomain.CurrentDomain.SetData(".hostingVirtualPath", virtualDir);
    AppDomain.CurrentDomain.SetData(".hostingInstallDir", HttpRuntime.AspInstallDirectory);
    TextWriter tw = new StringWriter();
    HttpWorkerRequest wr = new SimpleWorkerRequest("default.aspx", "", tw);
    HttpContext.Current = new HttpContext(wr);
}

Upvotes: 19

Siva
Siva

Reputation: 128

Using Microsoft Fakes we can fake VirtualPathUtility ToAbsolute Method easily.

  1. Browse System.Web in References > Right Click > Add Fakes Assembly.

Use Following Code

using Microsoft.QualityTools.Testing.Fakes;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Web.Fakes;

 public class TestCode
    {
        [TestMethod]
        public void TestSummaryTabLinks()
        {
            using (ShimsContext.Create())
            {
                //Fake VirtualPathUtility ToAbsolute method to Work properly in case of Unit Test Project
                //For Finding Relative url.
                ShimVirtualPathUtility.ToAbsoluteString = (string s) => { return s; };

                MyClass class = new MyClass( vpu );

                string actual = class.SomeMethod( path );

                Assert.AreEqual( expected, actual );

            }
      }

}

Upvotes: 3

tvanfosson
tvanfosson

Reputation: 532625

Static classes and methods are really hard to work with in unit tests (which is one reason why i try to avoid them). In this case, I would probably develop a wrapper around the static class, containing just those methods that I use. I would then use my wrapper class in place of the real class. The wrapper class would be constructed so that it is easy to mock out.

Example (sort of) using RhinoMocks. Note that it uses dependency injection to give the class under test a copy of the wrapper. If the supplied wrapper is null, it creates one.

public class MyClass
{
     private VPU_Wrapper VPU { get; set; }

     public MyClass() : this(null) {}

     public MyClass( VPU_Wrapper vpu )
     {
         this.VPU = vpu ?? new VPU_Wrapper();
     }

     public string SomeMethod( string path )
     {
         return this.VPU.ToAbsolute( path );
     }
}

public class VPU_Wrapper
{
    public virtual string ToAbsolute( string path )
    {
         return VirtualPathUtility.ToAbsolute( path );
    }
}

[TestMethod]
public void SomeTest()
{
     string path = "~/path";
     string expected = "/app/path";

     var vpu = MockRepository.GenerateMock<VPU_Wrapper>();
     vpu.Expect( v => v.ToAbsolute( path) ).Return( expected );

     MyClass class = new MyClass( vpu );

     string actual = class.SomeMethod( path );

     Assert.AreEqual( expected, actual );

     vpu.VerifyAllExpectations();
}

Upvotes: 8

Related Questions