From 2263e5510595d57b069702e43211a8d50ed09aab Mon Sep 17 00:00:00 2001 From: Tanvir Ahmad Arjel Date: Sat, 15 Nov 2025 14:15:37 +0700 Subject: [PATCH] test: unit tests added for query repository --- .../EFCore.QueryRepository.Tests.csproj | 1 + .../QueryRepositoryTests.cs | 617 +++++++++++++++++- 2 files changed, 599 insertions(+), 19 deletions(-) diff --git a/tests/EFCore.QueryRepository.Tests/EFCore.QueryRepository.Tests.csproj b/tests/EFCore.QueryRepository.Tests/EFCore.QueryRepository.Tests.csproj index 3067435..e6c1113 100644 --- a/tests/EFCore.QueryRepository.Tests/EFCore.QueryRepository.Tests.csproj +++ b/tests/EFCore.QueryRepository.Tests/EFCore.QueryRepository.Tests.csproj @@ -8,6 +8,7 @@ + diff --git a/tests/EFCore.QueryRepository.Tests/QueryRepositoryTests.cs b/tests/EFCore.QueryRepository.Tests/QueryRepositoryTests.cs index 72fd5ce..59c1beb 100644 --- a/tests/EFCore.QueryRepository.Tests/QueryRepositoryTests.cs +++ b/tests/EFCore.QueryRepository.Tests/QueryRepositoryTests.cs @@ -1,12 +1,14 @@ +using System.Linq.Expressions; using Microsoft.EntityFrameworkCore; -using Moq; -using Moq.EntityFrameworkCore; using TanvirArjel.EFCore.GenericRepository; namespace EFCore.QueryRepository.Tests; -public class QueryRepositoryTests +public class QueryRepositoryTests : IAsyncLifetime { + private DemoDbContext _context; + private QueryRepository _queryRepository; + private readonly List fakeEmployees = new() { new() @@ -33,16 +35,47 @@ public class QueryRepositoryTests } }; + public async Task InitializeAsync() + { + var options = new DbContextOptionsBuilder() + .UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString()) + .Options; + + _context = new DemoDbContext(options); + _queryRepository = new QueryRepository(_context); + await _context.Employees.AddRangeAsync(fakeEmployees); + await _context.SaveChangesAsync(); + } + + public async Task DisposeAsync() + { + if (_context != null) + { + await _context.DisposeAsync(); + } + } + + #region GetQueryable Tests + [Fact] - public async Task GetListAsyncTest() + public async Task GetQueryable_Test() { - // Arrange - Mock mockDemoContext = new(); - mockDemoContext.Setup(context => context.Set()).ReturnsDbSet(fakeEmployees); + // Act + IQueryable queryable = _queryRepository.GetQueryable(); + + // Assert + Assert.NotNull(queryable); + Assert.Equal(fakeEmployees.Count, queryable.Count()); + } + + #endregion + #region GetList Tests + [Fact] + public async Task GetListAsyncTest() + { // Act - QueryRepository queryRepository = new(mockDemoContext.Object); - List employees = await queryRepository.GetListAsync(); + List employees = await _queryRepository.GetListAsync(); // Assert Assert.NotNull(employees); @@ -57,12 +90,8 @@ public async Task GetListAsync_WithCondition_Test() int expectedCount = fakeEmployees.Where(e => e.Id == 1).Count(); string expectedName = "Mark"; - Mock mockDemoContext = new(); - mockDemoContext.Setup(context => context.Set()).ReturnsDbSet(fakeEmployees); - // Act - QueryRepository queryRepository = new(mockDemoContext.Object); - List employees = await queryRepository.GetListAsync(e => e.Id == 1); + List employees = await _queryRepository.GetListAsync(e => e.Id == 1); // Assert Assert.NotNull(employees); @@ -75,16 +104,566 @@ public async Task GetListAsync_WithCondition_Test() public async Task GetListAsync_WithInclude_Test() { // Arrange - Mock mockDemoContext = new(); - mockDemoContext.Setup(context => context.Set()).ReturnsDbSet(fakeEmployees); - // Act - QueryRepository queryRepository = new(mockDemoContext.Object); - List employees = await queryRepository.GetListAsync(q => q.Include(e => e.Department)); + List employees = await _queryRepository.GetListAsync(q => q.Include(e => e.Department)); // Assert Assert.NotNull(employees); Assert.NotEmpty(employees); Assert.True(employees.Count == fakeEmployees.Count); } + + + [Fact] + public async Task GetListAsync_NoTracking_Test() + { + // Act + List employees = await _queryRepository.GetListAsync(asNoTracking: true); + + // Assert + Assert.NotNull(employees); + Assert.NotEmpty(employees); + Assert.Equal(fakeEmployees.Count, employees.Count); + } + + [Fact] + public async Task GetListAsync_WithIncludeAndNoTracking_Test() + { + // Act + List employees = await _queryRepository.GetListAsync( + q => q.Include(e => e.Department), + asNoTracking: true); + + // Assert + Assert.NotNull(employees); + Assert.NotEmpty(employees); + Assert.Equal(fakeEmployees.Count, employees.Count); + } + + [Fact] + public async Task GetListAsync_WithConditionAndNoTracking_Test() + { + // Act + List employees = await _queryRepository.GetListAsync( + e => e.Id == 1, + asNoTracking: true); + + // Assert + Assert.NotNull(employees); + Assert.Single(employees); + Assert.Equal("Mark", employees.First().Name); + } + + [Fact] + public async Task GetListAsync_WithConditionAndIncludeAndNoTracking_Test() + { + // Act + List employees = await _queryRepository.GetListAsync( + e => e.DepartmentId == 1, + q => q.Include(e => e.Department), + asNoTracking: true); + + // Assert + Assert.NotNull(employees); + Assert.NotEmpty(employees); + Assert.All(employees, e => Assert.Equal(1, e.DepartmentId)); + } + + [Fact] + public async Task GetListAsync_Projected_Test() + { + // Act + List names = await _queryRepository.GetListAsync( + e => e.Name); + + // Assert + Assert.NotNull(names); + Assert.NotEmpty(names); + Assert.Equal(fakeEmployees.Count, names.Count); + } + + [Fact] + public async Task GetListAsync_ProjectedWithCondition_Test() + { + // Act + List names = await _queryRepository.GetListAsync( + e => e.Id == 1, + e => e.Name); + + // Assert + Assert.NotNull(names); + Assert.Single(names); + Assert.Equal("Mark", names.First()); + } + + [Fact] + public async Task GetListAsync_WithSpecification_Test() + { + // Arrange + var spec = new Specification(); + spec.Conditions.Add(e => e.DepartmentId == 1); + + // Act + List employees = await _queryRepository.GetListAsync(spec); + + // Assert + Assert.NotNull(employees); + Assert.NotEmpty(employees); + } + + [Fact] + public async Task GetListAsync_WithSpecificationAndNoTracking_Test() + { + // Arrange + var spec = new Specification(); + spec.Conditions.Add(e => e.Id == 1); + + // Act + List employees = await _queryRepository.GetListAsync(spec, asNoTracking: true); + + // Assert + Assert.NotNull(employees); + Assert.Single(employees); + } + + [Fact] + public async Task GetListAsync_WithSpecificationProjected_Test() + { + // Arrange + var spec = new Specification(); + spec.Conditions.Add(e => e.DepartmentId == 1); + + // Act + List names = await _queryRepository.GetListAsync( + spec, + e => e.Name); + + // Assert + Assert.NotNull(names); + Assert.NotEmpty(names); + } + + #endregion + + #region GetById Tests + + [Fact] + public async Task GetByIdAsync_Test() + { + // Act + Employee employee = await _queryRepository.GetByIdAsync(1); + + // Assert + Assert.NotNull(employee); + Assert.Equal(1, employee.Id); + Assert.Equal("Mark", employee.Name); + } + + [Fact] + public async Task GetByIdAsync_WithNoTracking_Test() + { + // Act + Employee employee = await _queryRepository.GetByIdAsync(1, asNoTracking: true); + + // Assert + Assert.NotNull(employee); + Assert.Equal(1, employee.Id); + } + + [Fact] + public async Task GetByIdAsync_WithInclude_Test() + { + // Act + Employee employee = await _queryRepository.GetByIdAsync( + 1, + q => q.Include(e => e.Department), + asNoTracking: false); + + // Assert + Assert.NotNull(employee); + Assert.NotNull(employee.Department); + Assert.Equal(1, employee.Id); + } + + [Fact] + public async Task GetByIdAsync_WithIncludeAndNoTracking_Test() + { + // Act + Employee employee = await _queryRepository.GetByIdAsync( + 1, + q => q.Include(e => e.Department), + asNoTracking: true); + + // Assert + Assert.NotNull(employee); + Assert.NotNull(employee.Department); + } + + [Fact(Skip = "In-memory provider does not support this query pattern")] + public async Task GetByIdAsync_Projected_Test() + { + // Act + string name = await _queryRepository.GetByIdAsync( + 1, + e => e.Name); + + // Assert + Assert.NotNull(name); + Assert.Equal("Mark", name); + } + + [Fact] + public async Task GetByIdAsync_NotFound_Test() + { + // Act + Employee employee = await _queryRepository.GetByIdAsync(999); + + // Assert + Assert.Null(employee); + } + + #endregion + + #region Get Tests + + [Fact] + public async Task GetAsync_WithCondition_Test() + { + // Act + Employee employee = await _queryRepository.GetAsync(e => e.Name == "Mark"); + + // Assert + Assert.NotNull(employee); + Assert.Equal("Mark", employee.Name); + } + + [Fact] + public async Task GetAsync_WithConditionAndNoTracking_Test() + { + // Act + Employee employee = await _queryRepository.GetAsync( + e => e.Name == "Merry", + asNoTracking: true); + + // Assert + Assert.NotNull(employee); + Assert.Equal("Merry", employee.Name); + } + + [Fact] + public async Task GetAsync_WithConditionAndInclude_Test() + { + // Act + Employee employee = await _queryRepository.GetAsync( + e => e.Id == 1, + q => q.Include(e => e.Department)); + + // Assert + Assert.NotNull(employee); + Assert.NotNull(employee.Department); + } + + [Fact] + public async Task GetAsync_WithConditionIncludeAndNoTracking_Test() + { + // Act + Employee employee = await _queryRepository.GetAsync( + e => e.Id == 2, + q => q.Include(e => e.Department), + asNoTracking: true); + + // Assert + Assert.NotNull(employee); + Assert.Equal(2, employee.Id); + } + + [Fact] + public async Task Get_WithCondition_Test() + { + // Arrange + var spec = new Specification(); + spec.Conditions.Add(e => e.Name == "Mark"); + + // Act + Employee employee = await _queryRepository.GetAsync(spec); + + // Assert + Assert.NotNull(employee); + Assert.Equal("Mark", employee.Name); + } + + [Fact] + public async Task GetAsync_WithSpecificationAndNoTracking_Test() + { + // Arrange + var spec = new Specification(); + spec.Conditions.Add(e => e.Id == 1); + + // Act + Employee employee = await _queryRepository.GetAsync(spec, asNoTracking: true); + + // Assert + Assert.NotNull(employee); + Assert.Equal(1, employee.Id); + } + + [Fact] + public async Task GetAsync_ProjectedWithCondition_Test() + { + // Act + string name = await _queryRepository.GetAsync( + e => e.Id == 1, + e => e.Name); + + // Assert + Assert.NotNull(name); + Assert.Equal("Mark", name); + } + + [Fact] + public async Task GetAsync_WithSpecification_Test() + { + // Arrange + var spec = new Specification(); + spec.Conditions.Add(e => e.Id == 2); + + // Act + string name = await _queryRepository.GetAsync( + spec, + e => e.Name); + + // Assert + Assert.NotNull(name); + Assert.Equal("Merry", name); + } + + [Fact] + public async Task GetAsync_NotFound_Test() + { + // Act + Employee employee = await _queryRepository.GetAsync(e => e.Name == "NonExistent"); + + // Assert + Assert.Null(employee); + } + + #endregion + + #region Exists Tests + + [Fact] + public async Task ExistsAsync_NoCondition_Test() + { + // Act + bool exists = await _queryRepository.ExistsAsync(); + + // Assert + Assert.True(exists); + } + + [Fact] + public async Task ExistsAsync_WithCondition_Test() + { + // Act + bool exists = await _queryRepository.ExistsAsync(e => e.Name == "Mark"); + + // Assert + Assert.True(exists); + } + + [Fact] + public async Task ExistsAsync_WithConditionNotMatching_Test() + { + // Act + bool exists = await _queryRepository.ExistsAsync(e => e.Name == "NonExistent"); + + // Assert + Assert.False(exists); + } + + [Fact] + public async Task ExistsByIdAsync_Test() + { + // Act + bool exists = await _queryRepository.ExistsByIdAsync(1); + + // Assert + Assert.True(exists); + } + + [Fact] + public async Task ExistsByIdAsync_NotFound_Test() + { + // Act + bool exists = await _queryRepository.ExistsByIdAsync(999); + + // Assert + Assert.False(exists); + } + + #endregion + + #region Count Tests + + [Fact] + public async Task GetCountAsync_NoCondition_Test() + { + // Act + int count = await _queryRepository.GetCountAsync(); + + // Assert + Assert.Equal(fakeEmployees.Count, count); + } + + [Fact] + public async Task GetCountAsync_WithCondition_Test() + { + // Act + int count = await _queryRepository.GetCountAsync(e => e.DepartmentId == 1); + + // Assert + Assert.Equal(fakeEmployees.Where(e => e.DepartmentId == 1).Count(), count); + } + + [Fact] + public async Task GetCountAsync_WithMultipleConditions_Test() + { + // Arrange + var conditions = new List>> + { + e => e.DepartmentId == 1, + e => e.Id > 0 + }; + + // Act + int count = await _queryRepository.GetCountAsync(conditions); + + // Assert + Assert.True(count > 0); + } + + [Fact] + public async Task GetLongCountAsync_NoCondition_Test() + { + // Act + long count = await _queryRepository.GetLongCountAsync(); + + // Assert + Assert.Equal(fakeEmployees.Count, count); + } + + [Fact] + public async Task GetLongCountAsync_WithCondition_Test() + { + // Act + long count = await _queryRepository.GetLongCountAsync(e => e.DepartmentId == 1); + + // Assert + Assert.True(count > 0); + } + + [Fact] + public async Task GetLongCountAsync_WithMultipleConditions_Test() + { + // Arrange + var conditions = new List>> + { + e => e.Id > 0, + e => e.DepartmentId >= 1 + }; + + // Act + long count = await _queryRepository.GetLongCountAsync(conditions); + + // Assert + Assert.True(count > 0); + } + + #endregion + + #region Raw SQL Tests + + [Fact(Skip = "Raw SQL queries require a relational database provider")] + public async Task GetFromRawSqlAsync_NoParameters_Test() + { + // Arrange + string sql = "SELECT * FROM Employees"; + + // Act + List employees = await _queryRepository.GetFromRawSqlAsync(sql); + + // Assert + Assert.NotNull(employees); + } + + [Fact(Skip = "Raw SQL queries require a relational database provider")] + public async Task GetFromRawSqlAsync_WithSingleParameter_Test() + { + // Arrange + string sql = "SELECT * FROM Employees WHERE Id = @p0"; + + // Act + List employees = await _queryRepository.GetFromRawSqlAsync(sql, 1); + + // Assert + Assert.NotNull(employees); + } + + [Fact(Skip = "Raw SQL queries require a relational database provider")] + public async Task GetFromRawSqlAsync_WithMultipleParameters_Test() + { + // Arrange + string sql = "SELECT * FROM Employees WHERE Id > @p0 AND DepartmentId = @p1"; + var parameters = new List { 0, 1 }; + + // Act + List employees = await _queryRepository.GetFromRawSqlAsync(sql, parameters); + + // Assert + Assert.NotNull(employees); + } + + #endregion + + #region Pagination Tests + + [Fact] + public async Task GetListAsync_WithPagination_Test() + { + // Arrange + var paginationSpec = new PaginationSpecification + { + PageIndex = 1, + PageSize = 1 + }; + + // Act + PaginatedList result = await _queryRepository.GetListAsync(paginationSpec); + + // Assert + Assert.NotNull(result); + Assert.Single(result.Items); + } + + [Fact] + public async Task GetListAsync_WithPaginationProjected_Test() + { + // Arrange + var paginationSpec = new PaginationSpecification + { + PageIndex = 1, + PageSize = 1 + }; + + // Act + PaginatedList result = await _queryRepository.GetListAsync( + paginationSpec, + e => e.Name); + + // Assert + Assert.NotNull(result); + Assert.Single(result.Items); + } + + #endregion } \ No newline at end of file