Table of Contents
C# Unit Testing Objects, IEnumerables, and Dates
In a previous post we looked at an introduction to Unit Testing, I want to expand on that and start looking at different data types. To do this I added some additional content to the UserService class.
namespace UnitTesting
{
public class UserService
{
public User GetUserById(int userId)
{
return new User {
Id = userId,
Name = "John Doe",
CreationDate = new DateOnly(2024,6,14) };
}
public DateOnly GetCreationDate(int userId)
{
return new DateOnly(2024,6,14);
}
public IEnumerable<User> GetUsers()
{
return new []
{
new User { Id = 1, Name = "John Doe", CreationDate = new DateOnly(2024,6,28) },
new User { Id = 2, Name = "Jane Doe", CreationDate = new DateOnly(1998,5,14) },
new User { Id = 3, Name = "John Smith", CreationDate = new DateOnly(1978,8,5) }
};
}
}
public class User
{
public int Id { get; set; } = 0;
public string Name { get; set; } = string.Empty;
public DateOnly? CreationDate { get; set; } = null;
}
}
Date
Using Fluent Assertions gives us a large number of Test, a complete list can be found here. I have used some of these to test the Creation Date method within the User Service.
[Fact]
public void UserService_GetCreationDate_ReturnDate()
{
// Arrange
var userService = new UserService();
int userId = 1;
// Act
var result = userService.GetCreationDate(userId);
// Assert
result.Should().NotBe(default);
result.Should().Be(new DateOnly(2024,6,14));
result.Should().BeAfter(new DateOnly(2024, 6, 13));
result.Year.Should().Be(2024);
result.Month.Should().Be(6);
result.Day.Should().Be(14);
result.DayOfWeek.Should().Be(DayOfWeek.Friday);
result.DayOfYear.Should().Be(166);
}
Object
This time were going to test an Object, to do so I’m going to re-use the GetUserById method again. However we need to clean something up first, in each Test Case we New’d up the userService. To keep this cleaner we will create a private member and move the new to the constructor, and then update the already created tests to use the private member.
public class UserServiceTest
{
private UserService _userService;
public UserServiceTest()
{
_userService = new UserService();
}
Now we can test the Object, here we have two test;
- BeofType<TypeName> – Validates that the correct type is returned.
- BeEquivalentTo – Does a Parity Check between two objects, this validates that all the property values are identical.
[Fact]
public void UserService_GetUserById_ReturnNewUser()
{
// Arrange
int userId = 1;
// Act
var result = _userService.GetUserById(userId);
// Assert
result.Should().BeOfType<User>();
result.Should().BeEquivalentTo(new User
{
Id = userId,
Name = "John Doe",
CreationDate = new DateOnly(2024,6,14)
});
}
IEnumerable
With an IEnumerable we can again check the Type, but we also have content checks to ensure that the contents of the IEnumerable are correct.
[Fact]
public void UserService_GetAllUsers_ReturnAllUsers()
{
// Arrange
// Act
var result = _userService.GetAllUsers();
// Assert
result.Should().BeOfType<User[]>();
result.Should().ContainEquivalentOf(new User
{
Id = 1,
Name = "John Doe",
CreationDate = new DateOnly(2024, 6, 28)
});
result.Should().Contain(x=> x.Id == 2 && x.Name == "Jane Doe");
}