Zrozumienie Asercji w xUnit: Kluczowe Metody i Ich Zastosowanie
Zrozumienie Asercji w xUnit: Kluczowe Metody i Ich Zastosowanie
Assert.Raises
Assert.Raises jest używana do sprawdzania, czy określone zdarzenie zostało wywołane. Jest to przydatne w testowaniu interfejsów użytkownika lub innych komponentów, które polegają na zdarzeniach do komunikacji stanu.
Prosty przykład:
[Fact]
public void TestEventRaises()
{
// Arrange
// Tworzenie publikującego zdarzenia
var eventPublisher = new EventPublisher();
// Act & Assert
Assert.Raises<EventArgs>(
handler => eventPublisher.MyEvent += handler, // Rejestracja handlera zdarzenia
handler => eventPublisher.MyEvent -= handler, // Usunięcie handlera zdarzenia
() => eventPublisher.TriggerEvent()); // Wywołanie metody, która wyzwala zdarzenie
}
Przykład z mockowaniem:
[Fact]
public void TestEventRaisesWithMock()
{
// Arrange
// Tworzenie mocka publikującego zdarzenia
var mockEventPublisher = new Mock<IEventPublisher>();
// Act
// Wywołanie metody wyzwalającej zdarzenie
mockEventPublisher.Object.TriggerEvent();
// Assert
// Symulowanie zgłoszenia zdarzenia
mockEventPublisher.Raise(m => m.MyEvent += null, EventArgs.Empty);
}
Assert.RaisesAny
Assert.RaisesAny sprawdza, czy podczas wykonania określonej akcji zostanie wygenerowane zdarzenie odpowiadające dowolnemu typowi z klasy EventArgs.
Prosty przykład:
[Fact]
public void EventRaisesAnyException()
{
// Arrange
// Tworzenie instancji obiektu, który publikuje zdarzenia
var publisher = new EventPublisher();
// Act & Assert
Assert.RaisesAny<EventArgs>(
handler => publisher.MyEvent += handler, // Rejestracja handlera zdarzenia
handler => publisher.MyEvent -= handler, // Odrejestrowanie handlera zdarzenia
() => publisher.TriggerEvent()); // Wywołanie metody, która wyzwala zdarzenie
}
Przykład z mockowaniem:
[Fact]
public void TestEventRaisesAnyWithMock()
{
// Arrange
// Tworzenie mocka publikującego zdarzenia
var mockEventPublisher = new Mock<IEventPublisher>();
// Tworzenie argumentów dla zdarzenia
var eventArgs = new CustomEventArgs();
// Konfiguracja mocka, aby symulować wywołanie zdarzenia przy wywołaniu TriggerEvent
mockEventPublisher.Setup(p => p.TriggerEvent())
.Raises("MyEvent", eventArgs);
// Act & Assert
Assert.RaisesAny<EventArgs>(
handler => mockEventPublisher.Object.MyEvent += handler, // Dodawanie obsługi zdarzeń
handler => mockEventPublisher.Object.MyEvent -= handler, // Usuwanie obsługi zdarzeń
() => mockEventPublisher.Object.TriggerEvent()); // Wywołanie metody, która powinna wyzwolić zdarzenie
}
Assert.RaisesAnyAsync
Assert.RaisesAnyAsync jest asynchroniczną wersją Assert.RaisesAny, używaną do testowania, czy asynchroniczne zdarzenie zostanie wywołane w trakcie wykonania podanej akcji asynchronicznej.
Prosty przykład:
[Fact]
public async Task EventRaisesAnyExceptionAsync()
{
// Arrange
// Tworzenie instancji obiektu, który publikuje zdarzenia asynchronicznie
var publisher = new AsyncEventPublisher();
// Act & Assert
await Assert.RaisesAnyAsync<EventArgs>(
handler => publisher.MyEvent += handler, // Rejestracja handlera zdarzenia
handler => publisher.MyEvent -= handler, // Odrejestrowanie handlera zdarzenia
() => publisher.TriggerEventAsync()); // Wywołanie asynchronicznej metody, która wyzwala zdarzenie
}
Przykład z mockowaniem:
[Fact]
public async Task TestEventRaisesAnyAsyncWithMock()
{
// Arrange
// Tworzenie mocka asynchronicznie publikującego zdarzenia
var mockEventPublisher = new Mock<IAsyncEventPublisher>();
// Tworzenie argumentów dla zdarzenia
var eventArgs = new CustomEventArgs();
// Konfiguracja mocka, aby symulować wywołanie asynchronicznego zdarzenia przy wywołaniu TriggerEventAsync
mockEventPublisher.Setup(p => p.TriggerEventAsync())
.RaisesAsync("MyAsyncEvent", eventArgs);
// Act & Assert
await Assert.RaisesAnyAsync<EventArgs>(
handler => mockEventPublisher.Object.MyAsyncEvent += handler, // Dodawanie obsługi zdarzeń
handler => mockEventPublisher.Object.MyAsyncEvent -= handler, // Usuwanie obsługi zdarzeń
() => mockEventPublisher.Object.TriggerEventAsync()); // Wywołanie asynchronicznej metody, która powinna wyzwolić zdarzenie
}
Assert.RaisesAsync
Assert.RaisesAsync jest używana do sprawdzania, czy asynchroniczne zdarzenie jest zgłaszane w trakcie wykonania określonej akcji asynchronicznej. Jest to przydatne w testowaniu komponentów, które wykorzystują zdarzenia w kontekście asynchronicznym.
Prosty przykład:
[Fact]
public async Task EnsureEventIsRaisedAsync()
{
// Arrange
// Tworzenie instancji obiektu, który publikuje zdarzenia
var publisher = new AsyncEventPublisher();
// Act & Assert
await Assert.RaisesAsync<EventArgs>(
handler => publisher.MyEvent += handler, // Dodanie handlera do zdarzenia
handler => publisher.MyEvent -= handler, // Usunięcie handlera zdarzenia
() => publisher.TriggerEventAsync()); // Wywołanie metody, która powinna wyzwolić zdarzenie
}
Przykład z mockowaniem:
[Fact]
public async Task EnsureAsyncEventIsRaised()
{
// Arrange
// Tworzenie mocka dla klasy publikującej zdarzenia asynchronicznie
var mockEventPublisher = new Mock<IAsyncEventPublisher>();
// Tworzenie argumentów dla zdarzenia
var eventArgs = new CustomEventArgs();
// Konfiguracja mocka, aby wywołać asynchroniczne zdarzenie
mockEventPublisher.Setup(p => p.TriggerEventAsync()).RaisesAsync("MyAsyncEvent", eventArgs);
// Act & Assert
await Assert.RaisesAsync<CustomEventArgs>(
handler => mockEventPublisher.Object.MyAsyncEvent += handler, // Subskrypcja zdarzenia
handler => mockEventPublisher.Object.MyAsyncEvent -= handler, // Rezygnacja z subskrypcji zdarzenia
() => mockEventPublisher.Object.TriggerEventAsync()); // Wywołanie metody, która powinna wyzwolić zdarzenie
}
Assert.ReferenceEquals
Assert.ReferenceEquals służy do sprawdzania, czy dwie zmienne wskazują na tę samą instancję obiektu. Jest to istotne, gdy ważna jest nie tylko równość wartości, ale identyczność obiektów.
Prosty przykład:
[Fact]
public void ObjectsReferenceEquals()
{
// Arrange
var objectA = new object(); // Tworzenie obiektu A
var objectB = objectA; // Przypisanie referencji obiektu A do obiektu B
// Act & Assert
// Sprawdzenie, czy oba obiekty to ta sama instancja
Assert.True(Object.ReferenceEquals(objectA, objectB));
}
Przykład z mockowaniem:
[Fact]
public void ConfigurationUsesSingletonPattern()
{
// Arrange
// Tworzenie mocka dla konfiguracji
var mockConfig = new Mock<IConfiguration>();
// Pobieranie instancji konfiguracji
var configInstance = mockConfig.Object;
// Pobieranie tej samej instancji konfiguracji ponownie
var anotherInstance = mockConfig.Object;
// Act & Assert
// Sprawdzanie, czy obie referencje wskazują na tę samą instancję
Assert.True(Object.ReferenceEquals(configInstance, anotherInstance));
}
Assert.Same
Assert.Same sprawdza, czy dwa obiekty są dokładnie tym samym obiektem (tj. mają tę samą referencję).
Prosty przykład:
[Fact]
public void ObjectsAreSame()
{
// Arrange
var objectA = new object(); // Tworzenie obiektu A
var objectB = objectA; // Przypisanie referencji obiektu A do obiektu B
// Act & Assert
// Sprawdzenie, czy oba obiekty to ta sama referencja
Assert.Same(objectA, objectB);
}
Przykład z mockowaniem:
[Fact]
public void ServiceReturnsSameInstanceEachTime()
{
// Arrange
// Tworzenie mocka dla fabryki usług
var mockFactory = new Mock<IServiceFactory>();
// Tworzenie instancji usługi
var serviceInstance = new SomeService();
// Konfiguracja, aby zawsze zwracać tę samą instancję usługi
mockFactory.Setup(f => f.CreateService()).Returns(serviceInstance);
// Act
// Pobieranie usługi po raz pierwszy
var service1 = mockFactory.Object.CreateService();
// Pobieranie usługi po raz drugi
var service2 = mockFactory.Object.CreateService();
// Assert
// Sprawdzanie, czy obie usługi to ta sama instancja
Assert.Same(service1, service2);
}
Assert.Single
Assert.Single sprawdza, czy kolekcja zawiera dokładnie jeden element.
Prosty przykład:
[Fact]
public void ListHasSingleElement()
{
// Arrange
// Tworzenie listy z jednym elementem
var elements = new List<string> { "apple" };
// Act & Assert
// Potwierdzenie, że lista zawiera dokładnie jeden element
Assert.Single(elements);
}
Przykład z mockowaniem:
[Fact]
public void SingleUserFoundWithRoleAdmin()
{
// Arrange
var mockUserRepository = new Mock<IUserRepository>();
// Konfiguracja mocka, aby zwracał jednego użytkownika z rolą Admin
mockUserRepository.Setup(repo => repo.FindUsersByRole("Admin"))
.Returns(new List<User>
{
new User { Role = "Admin" }
});
// Tworzenie serwisu z zmockowanym repozytorium
var userService = new UserService(mockUserRepository.Object);
// Act
// Pobranie użytkowników z rolą Admin
var users = userService.GetUsersByRole("Admin");
// Assert
// Potwierdzenie, że dokładnie jeden użytkownik został znaleziony
Assert.Single(users);
}
Assert.StartsWith
Assert.StartsWith weryfikuje, czy dany ciąg tekstowy zaczyna się od określonego podciągu.
Prosty przykład:
[Fact]
public void StringStartsWithPrefix()
{
// Arrange
// Definicja ciągu znaków
string value = "unittest";
// Act & Assert
// Sprawdzenie, czy ciąg zaczyna się od "unit"
Assert.StartsWith("unit", value);
}
Przykład z mockowaniem:
[Fact]
public void UsernamesStartWithPrefix()
{
// Arrange
// Tworzenie mocka dla repozytorium użytkowników
var mockUserRepository = new Mock<IUserRepository>();
// Konfiguracja, aby zwracać listę nazw użytkowników
mockUserRepository.Setup(repo => repo.GetUsernames())
.Returns(new List<string> { "adminJohn", "adminMike", "adminAnna" });
// Act
// Pobieranie nazw użytkowników
var usernames = mockUserRepository.Object.GetUsernames();
// Assert
foreach (var username in usernames)
{
// Sprawdzanie, czy każda nazwa użytkownika zaczyna się od "admin"
Assert.StartsWith("admin", username);
}
}
Assert.StrictEqual
Assert.StrictEqual wykonuje dokładne porównanie, biorąc pod uwagę typ i wartość. Różni się od Assert.Equal, który może czasami zezwalać na niejawne konwersje typów.
Prosty przykład:
[Fact]
public void ValuesAreStrictlyEqual()
{
// Arrange
int expected = 5; // Oczekiwana wartość jako liczba całkowita
int actual = 5; // Rzeczywista wartość jako liczba całkowita
// Act & Assert
// Sprawdzenie, czy wartości są ściśle równe
Assert.StrictEqual(expected, actual);
}
Przykład z mockowaniem:
[Fact]
public void CheckExactMatchOfComplexNumber()
{
// Arrange
// Tworzenie mocka dla kalkulatora
var mockCalculator = new Mock<ICalculator>();
// Tworzenie liczby zespolonej
var complexNumber = new ComplexNumber(5.0, 3.0);
// Konfiguracja, aby zwracać tę liczbę zespoloną przy dodawaniu
mockCalculator
.Setup(c => c.AddComplex(It.IsAny<ComplexNumber>(), It.IsAny<ComplexNumber>()))
.Returns(complexNumber);
// Act
// Dodawanie dwóch liczb zespolonych
var result = mockCalculator.Object.AddComplex(new ComplexNumber(2.0, 1.0), new ComplexNumber(3.0, 2.0));
// Assert
// Sprawdzanie, czy wynik jest dokładnie tą samą liczbą zespoloną
Assert.StrictEqual(complexNumber, result);
}
Assert.Subset
Assert.Subset sprawdza, czy jedna kolekcja jest podzbiorem innej. Weryfikuje, czy wszystkie elementy pierwszej kolekcji znajdują się w drugiej kolekcji.
Prosty przykład:
[Fact]
public void EnsureCollectionIsASubset()
{
// Arrange
var set = new HashSet<int> { 1, 2, 3, 4, 5 }; // Zbiór zawierający elementy
var subset = new HashSet<int> { 1, 2, 3 }; // Podzbiór
// Act & Assert
// Sprawdzenie, czy 'subset' jest podzbiorem 'set'
Assert.Subset(set, subset);
}
