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); }
