xUnit Theory: Jak używać InlineData, ClassData oraz MemberData

xUnit Theory: Jak używać InlineDate, ClassData lub MemberData

Ciąg dalszy cyklu o xUnit, oraz testowaniu aplikacji mobilnych w Xamarin.Forms.

Dzisiaj chciałbym omówić zastosowanie, oraz pokazać parę przykładów użycia Theory.

xUnit Theory: Jak używać InlineData, ClassData oraz MemberData

Czym jest Theory

Testy z atrybutem Theory umożliwiają nam przekazanie jako parametr danych wejściowych (może to być również kolekcja parametrów). Natomiast ich wynik jest poprawny tylko dla konkretnych dany wejściowych, czyli za jednym zamachem możemy przetestować pozytywne i negatywne przypadki.

Jak przekazać dane do metody

Żeby przekazać dane do metody możemy użyć jednego z 3 atrybutów InlineData, ClassData lub MemberData.

  • InlineData – umożliwia nam przekazanie danych typów prostych string, int, decimal, itd.
  • ClassData – umożliwia nam przekazanie typów złożonych
  • MemberData – umożliwia nam przekazanie typów złożonych z tą różnicą, że nie wymaga definiowania nowej klasy. Może to być dowolny obiekt, który zwraca IEnumerable

Przykłady użycia

Poniżej kilka przykładów implementacji każdego typu atrybutu.

InlineData

[code lang=”csharp”]
[Theory]
[InlineData("2017-04-15")]
[InlineData("2017-04-16")]
[InlineData("2017-04-17")]
public async void CanGetDifferentProblemsForEachDayWhichIsNotNull(DateTime currentDate)
{
//Arrange
IDataService service = new MockDataService();

//Act
Problem problem = await service.GetProblemByDateAsync(currentDate);

//Assert
Assert.NotNull(problem);
}
[/code]

ClassData

[code lang=”csharp”]
public class TodoItemsTestData : IEnumerable<object[]>
{
private readonly List<object[]> data = new List<object[]>
{
new object[] { Guid.NewGuid(), string.Empty, false, null},
new object[] { Guid.NewGuid(), "Buy tickets for movie", false, null },
new object[] { Guid.NewGuid(), string.Empty, false, null },
new object[] { Guid.NewGuid(), "Buy a milk", true, null },
};

public IEnumerator<object[]> GetEnumerator() => data.GetEnumerator();

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
….
[Theory]
[ClassData(typeof(TodoItemsTestData))]
public async void CantAddTodoItemWithoutTitle(Guid id, string title, bool done, DateTime? dueDate)
{
//Arrange
DataService service = new DataService();
TodoItem item = new TodoItem { Id = id, Name = title, Done = done, DueDate = dueDate };

//Act
var ex = await Assert.ThrowsAsync<ArgumentException>(() => service.AddTodoItemAsync(item));

//Assert
Assert.IsType<ArgumentException>(ex);

[/code]

MemberData

[code lang=”csharp”]
public class TodoTheoryData<T> : TheoryData<T>
{
public TodoTheoryData(IEnumerable<T> data)
{
foreach (T t1 in data)
{
Add(t1);
}
}
}
public class DataServiceTests
{
private static TodoItem[] todoItems = new TodoItem[]
{
new TodoItem { Id = Guid.NewGuid(), Name = "Buy a milk", Done = false, DueDate = null},
new TodoItem { Id = Guid.NewGuid(), Name = "Buy a TV", Done = false, DueDate = null},
new TodoItem { Id = Guid.NewGuid(), Name = "Buy a new iPhone", Done = false, DueDate = DateTime.Today},
new TodoItem { Id = Guid.NewGuid(), Name = "Buy a pomodoro", Done = false, DueDate = null},
new TodoItem { Id = Guid.NewGuid(), Name = "Buy a bread", Done = false, DueDate = null}
};

public static TodoTheoryData<TodoItem> TodoItemsData { get; } = new TodoTheoryData<TodoItem>(todoItems);

[Theory]
[MemberData(nameof(TodoItemsData))]
public async void InStorageAreFiveItems(TodoItem item)
{
//Arrange
DataService service = new DataService();
await service.AddTodoItemAsync(item);

//Act
IEnumerable<TodoItem> todoItems = await service.GetAllAsync();

//Assert
Assert.Equal(5, todoItems.Count());
}
}
[/code]

Podsumowanie

Jak widzicie użycie Theory daje nam dużo benefitów i ułatwia nam testowanie aplikacji mobilnych napisanych w Xamarin.Forms ale i nie tylko.

Z użyciem xUnit możemy testować całą pulę aplikacji na platformie .Net od aplikacji Desktop, Mobile aż po Web.

Pomocne linki

Jeżeli chcecie poczytać coś więcej o xUnit Theory to odsyłam was do poniższych linków:

Share