Search code examples
c#unit-testingfluentvalidation

Why I'm not getting 100% code coverage even after completing all the cases?


This is my query class:

public class GetRolesQuery : GenericDetailsPaginatedQueryBase
{
    public string[] OrganizationIds { get; set; } = [];
    public DateTime? FromDate { get; set; }
    public DateTime? ToDate { get; set; }
}

This is my validator class:

public class GetRolesQueryValidator : AbstractValidator<GetRolesQuery>
{
    private readonly IGenericMongoDbRepository _repository;

    public GetRolesQueryValidator(IGenericMongoDbRepository repository)
    {
        _repository = repository;

        RuleFor(x => x)
            .Must(x => x.FromDate <= x.ToDate)
            .WithMessage($"{nameof(GetRolesQuery.FromDate)} can not be greater than {nameof(GetRolesQuery.ToDate)}.")
            .When(x => x.FromDate != null && x.ToDate != null);
    }
}

What are the test cases do I need to test to get 100% coverage? I'm getting partial coverage for this x.FromDate <= x.ToDate with the following cases:

 
Case 1:
        var model = new GetRolesQuery 
        {
            FromDate = new DateTime(2025, 1, 10),
            ToDate = new DateTime(2025, 1, 5)
        };
 
Case 2:
        var model = new GetRolesQuery    
        {
            FromDate = new DateTime(2025, 1, 5),
            ToDate = new DateTime(2025, 1, 10)
        };

Case 3:
    var model = new GetRolesQuery     
        {
            FromDate = new DateTime(2025, 1, 10),
            ToDate = new DateTime(2025, 1, 10)
        };

Case 4:
    var model = new GetRolesQuery
        {
            FromDate = null,
            ToDate = null
        };

Case 5:
    var model = new GetRolesQuery
        {
            FromDate = null,
            ToDate = new DateTime(2025, 1, 10)
        };

Case 6:
    var model = new GetRolesQuery
        {
            FromDate = new DateTime(2025, 1, 10),
            ToDate = null
        };


Solution

  • The When causes the Rule to be skipped for the null cases, which then leads to the incomplete coverage result.

    It will work if you incorporate the When conditions into the Must and drop the When.

    Code:

    RuleFor(x => x)
      .Must(x => x.FromDate == null || x.ToDate == null || x.FromDate <= x.ToDate)
      .WithMessage($"{nameof(GetRolesQuery.FromDate)} can not be greater than {nameof(GetRolesQuery.ToDate)}.");