Microsoft Fakes and real object constructor

Raja, Kushal 0 Reputation points
2024-10-01T09:08:03.5166667+00:00

I'm using .NET 4.8 and Microsoft Fakes to create Shim object for unit testing. This class (KRSampleManager) is using Lazy initialization to create an instance and implements IDisposable interface.

namespace SampleManager
{
    public class KRSampleManager : IDisposable
    {
        private Dictionary<string, string> _events = null;
        private KRSampleManager() 
        {
            _events = new Dictionary<string, string>();
        }


        private static readonly Lazy<KRSampleManager> _lazy =
          new Lazy<KRSampleManager>
              (() => new KRSampleManager());

        private bool _isDisposed;

        protected virtual void Dispose(bool disposing)
        {
            if (_isDisposed && disposing)
            {
                _isDisposed = true;
            }
        }

        public static KRSampleManager Instance
        {
            get { return _lazy.Value; }
        }

        public void Dispose()
        {
            _events.Clear();
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        public int Count()
        {
           return _events.Count();
        }

        public bool IsNull()
        { return _events == null; }
    }
}


there is another SampleHandler class which is using the KRSampleManager class

namespace SampleHandler
{
    public class SampleHandler 
    {
        private bool _isnull;
        public SampleHandler()
        {
            _isnull = SampleManager.KRSampleManager.Instance.IsNull();
        }
    }
}

there are two unit test classes in same unit test project. UnitTest1 class creates a ShimKRSampleManager and tries to create SampleHandler object

public class UnitTest1
    {
        [TestMethod]
        public void TestMethod3() 
        {
            using (ShimsContext.Create())
            {
                ShimKRSampleManager.Constructor = (c) => { };
                var handler = new SampleHandler.SampleHandler();//SampleHandler.SampleHandler.Instance;
                Assert.IsNotNull(handler);
            }
        }
    }


UnitTest2 class just creates a real KRSampleManager instance and dispose it.

[TestClass]
    public class UnitTest2
    {
        [TestMethod]
        public void TestMethod2()
        {
            var s = KRSampleManager.Instance;
            s.Dispose();
        }
    }

When running unit tests, if UnitTest1 executes first, then UnitTest2 fails with System.NullReferenceException: Object reference not set to an instance of an object for KRSampleManager.Dispose() method for _events.Clear(). Adding logs indicate that the constructor for KRSampleManager never gets called if UnitTest1 test is run first. If I change the name of UnitTest1 class to UnitTest3, so that it executes after UnitTest2, both unit tests pass. This seems to be problem with Microsoft Fakes. If I keep UnitTest1 and UnitTes2 classes in separate project both tests pass.

C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
11,002 questions
Visual Studio Testing
Visual Studio Testing
Visual Studio: A family of Microsoft suites of integrated development tools for building applications for Windows, the web and mobile devices.Testing: The act or process of applying tests as a means of analysis or diagnosis.
351 questions
{count} votes

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.