niedziela, 30 grudnia 2018

[2] Visual Studio - NUnit Test - Podstawy testowania singletona

W tym krótkim poście chciałbym przedstawić sposób przeprowadzania testów jednostkowych na wzorcu projektowym singleton. 

[Źródło: https://docs.microsoft.com/en-us/dotnet/]


Program:


Singleton jest przeważnie wykorzystywany dla wprowadzenia komponentów, które będą zawierały parametry dostępne w wielu miejscach w klasie.

Singleton posiada tylko jedną instancję klasy w całej aplikacji.

Główną różnicą pomiędzy singletonem a zwykłą klasą statyczną jest możliwość implementowania interfejsu. Dodatkowo singleton pozwala na uzyskanie dostępu do stworzonej instancji, która może być przekazana jako parametr do innej metody. Co pozwala na używanie jej jak normalnego obiektu. Natomiast klasa statyczna zawiera tylko grupę statycznych metod.

Poniższe testy sprawdzają sposób testowania klasy Singleton, w celu upewnienia się, że został on przygotowany poprawnie.

Poniżej przykładowa klasa testowa:

  1. public sealed class SingletonExampleClass
  2. {
  3.     private static SingletonExampleClass singletonInstance = null;
  4.     private static readonly object singletonLock = new object();
  5.     private static uint _counter;
  6.  
  7.     private SingletonExampleClass()
  8.     {
  9.         _counter++;
  10.     }
  11.  
  12.     public static void SetBiggerCounterValue(uint data)
  13.     {
  14.         _counter = data;
  15.     }
  16.    
  17.     public static uint ReturnCounter()
  18.     {
  19.         return _counter;
  20.     }
  21.  
  22.     public static SingletonExampleClass Instance
  23.     {
  24.         get
  25.         {
  26.             lock (singletonLock)
  27.             {
  28.                 if (singletonInstance == null) {
  29.                     _counter = 0;
  30.                     singletonInstance = new SingletonExampleClass();
  31.                 }
  32.                 return singletonInstance;
  33.             }
  34.         }
  35.     }
  36.  
  37.     public void DoSomething()
  38.     {
  39.         Console.WriteLine("DoSomethin() - Use number: ", _counter++);
  40.     }
  41. }

Teraz przykładowy sposób testowania czy odpowiednio stworzyliśmy singletona. I oba obiekt są takie same:

  1. [Test]
  2. public void ExampleFunction_CheckIfEvantRises()
  3. {
  4.     var db = SingletonExampleClass.Instance;
  5.     var db2 = SingletonExampleClass.Instance;
  6.  
  7.     Assert.That(db, Is.SameAs(db2));
  8.     Assert.That(SingletonExampleClass.ReturnCounter() == 1);
  9. }

W związku z tym, że obiekt jest tworzony tylko i wyłączenie wewnątrz testu to jego wywołania nie mają wpływu na rozpoczęcie kolejnego testu. Co oznacza, że parametry ustawione w teście pierwszym w klasie singletona nie będą miały wpływu na wykonanie kolejnego testu. Problem pojawi się dopiero gdy w kilku testach będziemy wywoływać ten sam obiekt.