What's the best way to test with AutoFixture a function that uses a "Mapper"

Viewed 26

I have written an application which communicates with Auth0, using the official Auth0 NuGet package. The function in the Auth0 NuGet package which I call returns a collection of Users.

I map this collection to a domain object using an extension method:

NOTE: This class is an internal, class, it's not exposed to the outside world and it shouldn't be.

public static IEnumerable<UserModel> MapToUserModel(this IEnumerable<User> users)
{
    return users.Select(
        static user => new UserModel
        {
            Id = user.UserId,
            Email = user.Email,
            FirstName = user.FirstName,
            LastName = user.LastName,
            AvatarLink = user.Picture,
            LastSeen = user.LastLogin?.ToUnixTime(),
            Status = UserExtensions.GetStatus(user),
        });
}

private static UserStatus GetStatus(UserBase user)
{
    if (!user.EmailVerified.HasValue || !user.EmailVerified.Value)
    {
        return UserStatus.Inactive;
    }
    if (user.Blocked.HasValue && user.Blocked.Value)
    {
        return UserStatus.Pending;
    }
    if (!user.Blocked.HasValue || user.Blocked.HasValue && !user.Blocked.Value)
    {
        return UserStatus.Active;
    }
    return UserStatus.Inactive;
}

Here's the relevant domain model:

public sealed class UserModel
{
  public string? Id { get; init; }

  public string? Email { get; init; }

  public string? FirstName { get; init; }

  public string? LastName { get; init; }

  public string? AvatarLink { get; init; }

  public long? LastSeen { get; init; }

  public UserStatus Status { get; init; }
}

Now, I do have a function which communicates with Auth0 to retrieve a collection of users, and each of these users is mapped to a UserModel instance.

But now I am facing issues with how to test this properly. First of all, unit tests should only be testing the public API, so the mapper itself should be tested through the public API.

A simplified test looks like:

[Fact]
public void SimpleTest()
{
    // ARRANGE.
    var fixture = new Fixture();
    var auth0Users = fixture.CreateMany<User>();

    // NOTE: Here the function is called which in turns calls the mapping.
    var results = 

    // ASSERT.
    results.Should()
     .HaveCount(auth0Users.Count)
     .And.BeEquivalentTo(
          auth0Users.Select(
              static (user, _) => new UserModel
              {
                  Id = user.UserId,
                  Email = user.Email,
                  FirstName = user.FirstName,
                  LastName = user.LastName,
                  AvatarLink = user.Picture,
                  LastSeen = CalculateLastSeen(user.LastLogin),
                  Status = CalculateUserStatus(user),
              }),
          static options => options.Including(static x => x.Id)
                                   .Including(static x => x.Email)
                                   .Including(static x => x.FirstName)
                                   .Including(static x => x.LastName)
                                   .Including(static x => x.AvatarLink)
                                   .Including(static x => x.LastSeen)
                                   .Including(static x => x.Status));

    // HELPER FUNCTIONS.
    static long? CalculateLastSeen(DateTime? dateTime)
    {
    if (dateTime == null)
    {
        return null;
    }

    return new DateTimeOffset(((DateTime)dateTime).ToUniversalTime()).ToUnixTimeSeconds();
    }

    static UserStatus CalculateUserStatus(UserBase user)
    {
    if (!user.EmailVerified.HasValue || !user.EmailVerified.Value)
    {
        return UserStatus.Inactive;
    }

    if (user.Blocked.HasValue && user.Blocked.Value)
    {
        return UserStatus.Pending;
    }

    if (!user.Blocked.HasValue || user.Blocked.HasValue && !user.Blocked.Value)
    {
        return UserStatus.Active;
    }

    return UserStatus.Inactive;
    }
}

Of course, AutoFixture doesn't generate permutations of each possible value for EmailVerified and User.Blocked.

How should I test this with AutoFixture? Is something wrong with the design and should it be improved? If not, how can I configure AutoFixture to ensure that each permutation is going to be present in the collection?

0 Answers
Related