Search code examples
c#unit-testingmstest

How to run singleton method only once in multiple test projects


I have three test projects. All of them referenced from the Model project:

projects

I created the TestBase class in the Model project and using it as the base class of all test classes. Inheritance looks like this:

[TestClass]
    public class UnitTest1 : TestBase
    {
        [TestMethod]
        public void TestMethod1()
        {
        }
    }

In TestBase I have TestInitialize:

 [TestInitialize]
        public void Initialize()
        {
            SingletonClass.Initiate();
        }

        [TestCleanup]
        public void Cleanup()
        {
            //Do some
        }

SingletonClass is a static class that needs in tests. I need to initiate it once so I am doing this:

public static class SingletonClass
    {
        public static bool IsInitiated { get; set; }

        public static void Initiate()
        {
            if (!IsInitiated)
            {
                IsInitiated = true;
                //Do some
                Thread.Sleep(5000);
            }
        }
    }

It is working fine when I run tests of one project, but when I run all it is initiating it 3 times(took 15 seconds). Is there any way to run it only once when I run all tests?


Solution

  • Finally, I found a solution. I merged all projects into a new project (AllTests) using ILRepack:

     <!-- ILRepack -->
      <Target Name="ILRepack" AfterTargets="Build" Condition="'$(Configuration)' == 'Debug'">
        <PropertyGroup>
          <WorkingDirectory>$(OutputPath)</WorkingDirectory>
        </PropertyGroup>
        <ItemGroup>
          <InputAssemblies Include="$(OutputPath)MainTest.dll" />
          <InputAssemblies Include="$(OutputPath)FIrst.dll" />
          <InputAssemblies Include="$(OutputPath)Second.dll" />
          <InputAssemblies Include="$(OutputPath)Third.dll" />
        </ItemGroup>
        <Message Text="MERGING: @(InputAssemblies->'%(Filename)') into $(OutputAssembly)" Importance="High" />
        <ILRepack OutputType="$(OutputType)"  Internalize="false" MainAssembly="$(AssemblyName).dll" OutputAssembly="$(AssemblyName).dll" InputAssemblies="@(InputAssemblies)" WorkingDirectory="$(WorkingDirectory)" />
      </Target>
      <!-- /ILRepack -->
    

    Now, I can run all tests using vstest.console.exe:

    vstest.console.exe AllTests.dll
    

    Or I can run it from the visual studio:

    run test from vs

    Singleton class initiating only on time. I don't know how it affects negatively, but currently, it is working fine