Search code examples
c#unit-testingmstestmicrosoft-fakes

How to create Shim for System.AppDomain class?


In my code I am using AppDomain.CurrentDomain.BaseDirectory call.

In my unit test I want to fake this call, so it will always return same value for BaseDirectory property.

However, after generating fake assembly for System I can't see ShimAppDomain in my unit test. Is it becasue AppDomain is sealed class?

How can I isolate my test from AppDomain.CurrentDomain.BaseDirectory call?

For mocking using Microsoft Fakes Framework and Visual Studio 2015 Enterprise.


Solution

  • Found this solution

    I. Updated content of mscorlib.fakes to

    <Fakes xmlns="http://schemas.microsoft.com/fakes/2011/" Diagnostic="true">
      <Assembly Name="mscorlib" Version="4.0.0.0"/>
      <StubGeneration>
        <Clear/>
      </StubGeneration>
      <ShimGeneration>
        <Clear/>
        <Add FullName="System.AppDomain"/>
      </ShimGeneration>
    </Fakes>
    

    II. Added using System.Fakes to my Unit Test file

    III. Added following to my Unit Test

    using (ShimsContext.Create())
    {
        string baseDir = @"My\Base\Dir";
    
        ShimAppDomain fakeAppDomain = new ShimAppDomain()
        {
            BaseDirectoryGet = () => { return baseDir; }
        };
    
        ShimAppDomain.CurrentDomainGet = () => { return fakeAppDomain; };
    
        string defaultDir = MyConstants.DefaultAppFolder;
    
        // both baseDir and defaultDir are same "My\Base\Dir"
        Assert.AreEqual(baseDir, defaultDir);
    }
    

    Constants.DefaultAppFolder property is implemented as follows

    internal static class MyConstants
    {
        internal static string DefaultAppFolder
        {
            get
            {
                return AppDomain.CurrentDomain.BaseDirectory;
            }
        }
    }
    

    It is quite verbose, but works.