From 2023477b0e55c81db052f4a757846fb018146c24 Mon Sep 17 00:00:00 2001 From: Lazaro Ansaldi Date: Thu, 19 Sep 2024 18:06:35 -0300 Subject: [PATCH 1/8] Add support to ExecuteDelete and ExecuteUpdate --- .../MockQueryable.Core/TestQueryProvider.cs | 160 ++--- .../MockQueryable.EntityFrameworkCore.csproj | 2 +- .../MockQueryable.Sample.csproj | 1 + .../MockQueryable.Sample/MyService.cs | 177 +++--- .../MockQueryable.Sample/MyServiceMoqTests.cs | 588 ++++++++++-------- .../TestDbSetRepository.cs | 13 + 6 files changed, 513 insertions(+), 428 deletions(-) diff --git a/src/MockQueryable/MockQueryable.Core/TestQueryProvider.cs b/src/MockQueryable/MockQueryable.Core/TestQueryProvider.cs index 264b051..c5e2db2 100644 --- a/src/MockQueryable/MockQueryable.Core/TestQueryProvider.cs +++ b/src/MockQueryable/MockQueryable.Core/TestQueryProvider.cs @@ -6,78 +6,92 @@ namespace MockQueryable.Core { - public abstract class TestQueryProvider : IOrderedQueryable, IQueryProvider - { - private IEnumerable _enumerable; - - protected TestQueryProvider(Expression expression) - { - Expression = expression; - } - - protected TestQueryProvider(IEnumerable enumerable) - { - _enumerable = enumerable; - Expression = enumerable.AsQueryable().Expression; - } - - public IQueryable CreateQuery(Expression expression) - { - if (expression is MethodCallExpression m) - { - var resultType = m.Method.ReturnType; // it should be IQueryable - var tElement = resultType.GetGenericArguments().First(); - return (IQueryable) CreateInstance(tElement, expression); - } - - return CreateQuery(expression); - } - - public IQueryable CreateQuery(Expression expression) - { - return (IQueryable) CreateInstance(typeof(TEntity), expression); - } - - private object CreateInstance(Type tElement, Expression expression) + public abstract class TestQueryProvider : IOrderedQueryable, IQueryProvider { - var queryType = GetType().GetGenericTypeDefinition().MakeGenericType(tElement); - return Activator.CreateInstance(queryType, expression); - } - - public object Execute(Expression expression) - { - return CompileExpressionItem(expression); - } - - public TResult Execute(Expression expression) - { - return CompileExpressionItem(expression); - } - - IEnumerator IEnumerable.GetEnumerator() - { - if (_enumerable == null) _enumerable = CompileExpressionItem>(Expression); - return _enumerable.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - if (_enumerable == null) _enumerable = CompileExpressionItem>(Expression); - return _enumerable.GetEnumerator(); - } - - public Type ElementType => typeof(T); - - public Expression Expression { get; } - - public IQueryProvider Provider => this; - - private static TResult CompileExpressionItem(Expression expression) - { - var visitor = new TestExpressionVisitor(); - var body = visitor.Visit(expression); - var f = Expression.Lambda>(body ?? throw new InvalidOperationException($"{nameof(body)} is null"), (IEnumerable) null); - return f.Compile()(); - } - } + // Hardcoding this constants to avoid the reference to EFCore + private const string EF_EXECUTE_UPDATE_METHOD_NAME = "ExecuteUpdate"; + private const string EF_EXECUTE_DELETE_METHOD_NAME = "ExecuteDelete"; + + private IEnumerable _enumerable; + + protected TestQueryProvider(Expression expression) + { + Expression = expression; + } + + protected TestQueryProvider(IEnumerable enumerable) + { + _enumerable = enumerable; + Expression = enumerable.AsQueryable().Expression; + } + + public IQueryable CreateQuery(Expression expression) + { + if (expression is MethodCallExpression m) + { + var resultType = m.Method.ReturnType; // it should be IQueryable + var tElement = resultType.GetGenericArguments().First(); + return (IQueryable) CreateInstance(tElement, expression); + } + + return CreateQuery(expression); + } + + public IQueryable CreateQuery(Expression expression) + { + return (IQueryable) CreateInstance(typeof(TEntity), expression); + } + + private object CreateInstance(Type tElement, Expression expression) + { + var queryType = GetType().GetGenericTypeDefinition().MakeGenericType(tElement); + return Activator.CreateInstance(queryType, expression); + } + + public object Execute(Expression expression) + { + return CompileExpressionItem(expression); + } + + public TResult Execute(Expression expression) + { + if (expression is MethodCallExpression methodCall && (methodCall.Method.Name == EF_EXECUTE_UPDATE_METHOD_NAME || methodCall.Method.Name == EF_EXECUTE_DELETE_METHOD_NAME) + && typeof(TResult) == typeof(int)) + { + // Intercept ExecuteDelete and ExecuteUpdate calls + var affectedItems = CompileExpressionItem>(Expression).ToList(); + // Return the count of affected items + return (TResult)(object)affectedItems.Count; + } + + // Fall back to default expression execution + return CompileExpressionItem(expression); + } + + IEnumerator IEnumerable.GetEnumerator() + { + if (_enumerable == null) _enumerable = CompileExpressionItem>(Expression); + return _enumerable.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + if (_enumerable == null) _enumerable = CompileExpressionItem>(Expression); + return _enumerable.GetEnumerator(); + } + + public Type ElementType => typeof(T); + + public Expression Expression { get; } + + public IQueryProvider Provider => this; + + private static TResult CompileExpressionItem(Expression expression) + { + var visitor = new TestExpressionVisitor(); + var body = visitor.Visit(expression); + var f = Expression.Lambda>(body ?? throw new InvalidOperationException($"{nameof(body)} is null"), (IEnumerable) null); + return f.Compile()(); + } + } } \ No newline at end of file diff --git a/src/MockQueryable/MockQueryable.EntityFrameworkCore/MockQueryable.EntityFrameworkCore.csproj b/src/MockQueryable/MockQueryable.EntityFrameworkCore/MockQueryable.EntityFrameworkCore.csproj index 88963b3..7a6ff19 100644 --- a/src/MockQueryable/MockQueryable.EntityFrameworkCore/MockQueryable.EntityFrameworkCore.csproj +++ b/src/MockQueryable/MockQueryable.EntityFrameworkCore/MockQueryable.EntityFrameworkCore.csproj @@ -45,7 +45,7 @@ - + diff --git a/src/MockQueryable/MockQueryable.Sample/MockQueryable.Sample.csproj b/src/MockQueryable/MockQueryable.Sample/MockQueryable.Sample.csproj index 2ebe7d8..e83bcc4 100644 --- a/src/MockQueryable/MockQueryable.Sample/MockQueryable.Sample.csproj +++ b/src/MockQueryable/MockQueryable.Sample/MockQueryable.Sample.csproj @@ -6,6 +6,7 @@ + diff --git a/src/MockQueryable/MockQueryable.Sample/MyService.cs b/src/MockQueryable/MockQueryable.Sample/MyService.cs index 50d782b..aa4a159 100644 --- a/src/MockQueryable/MockQueryable.Sample/MyService.cs +++ b/src/MockQueryable/MockQueryable.Sample/MyService.cs @@ -1,108 +1,111 @@ -using System; +using AutoMapper; +using AutoMapper.QueryableExtensions; +using Microsoft.EntityFrameworkCore; +using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using AutoMapper; -using AutoMapper.QueryableExtensions; -using Microsoft.EntityFrameworkCore; namespace MockQueryable.Sample { - public class MyService - { - private readonly IUserRepository _userRepository; - - public static void Initialize() + public class MyService { - Mapper.Initialize(cfg => cfg.CreateMap() - .ForMember(dto => dto.FirstName, conf => conf.MapFrom(ol => ol.FirstName)) - .ForMember(dto => dto.LastName, conf => conf.MapFrom(ol => ol.LastName))); - Mapper.Configuration.AssertConfigurationIsValid(); + private readonly IUserRepository _userRepository; + + public static void Initialize() + { + Mapper.Initialize(cfg => cfg.CreateMap() + .ForMember(dto => dto.FirstName, conf => conf.MapFrom(ol => ol.FirstName)) + .ForMember(dto => dto.LastName, conf => conf.MapFrom(ol => ol.LastName))); + Mapper.Configuration.AssertConfigurationIsValid(); + } + + public MyService(IUserRepository userRepository) + { + _userRepository = userRepository; + } + + public async Task CreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth) + { + var query = _userRepository.GetQueryable(); + + if (await query.AnyAsync(x => x.LastName == lastName && x.DateOfBirth == dateOfBirth)) + { + throw new ApplicationException("User already exist"); + } + + var existUser = await query.FirstOrDefaultAsync(x => x.FirstName == firstName); + if (existUser != null) + { + throw new ApplicationException("User with FirstName already exist"); + } + + if (await query.CountAsync(x => x.DateOfBirth == dateOfBirth.Date) > 3) + { + throw new ApplicationException("Users with DateOfBirth more than limit"); + } + + await _userRepository.CreateUser(new UserEntity + { + FirstName = firstName, + LastName = lastName, + DateOfBirth = dateOfBirth.Date, + }); + + } + + public async Task> GetUserReports(DateTime dateFrom, DateTime dateTo) + { + var query = _userRepository.GetQueryable(); + + query = query.Where(x => x.DateOfBirth >= dateFrom.Date); + query = query.Where(x => x.DateOfBirth <= dateTo.Date); + + return await query.Select(x => new UserReport + { + FirstName = x.FirstName, + LastName = x.LastName, + }).ToListAsync(); + } + + + public async Task> GetUserReportsAutoMap(DateTime dateFrom, DateTime dateTo) + { + var query = _userRepository.GetQueryable(); + + query = query.Where(x => x.DateOfBirth >= dateFrom.Date); + query = query.Where(x => x.DateOfBirth <= dateTo.Date); + + return await query.ProjectTo().ToListAsync(); + } } - public MyService(IUserRepository userRepository) + public interface IUserRepository { - _userRepository = userRepository; - } + IQueryable GetQueryable(); - public async Task CreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth) - { - var query = _userRepository.GetQueryable(); - - if (await query.AnyAsync(x => x.LastName == lastName && x.DateOfBirth == dateOfBirth)) - { - throw new ApplicationException("User already exist"); - } - - var existUser = await query.FirstOrDefaultAsync(x => x.FirstName == firstName); - if (existUser != null) - { - throw new ApplicationException("User with FirstName already exist"); - } - - if (await query.CountAsync(x => x.DateOfBirth == dateOfBirth.Date) > 3) - { - throw new ApplicationException("Users with DateOfBirth more than limit"); - } - - await _userRepository.CreateUser(new UserEntity - { - FirstName = firstName, - LastName = lastName, - DateOfBirth = dateOfBirth.Date, - }); + Task CreateUser(UserEntity user); - } + Task> GetAll(); - public async Task> GetUserReports(DateTime dateFrom, DateTime dateTo) - { - var query = _userRepository.GetQueryable(); + IAsyncEnumerable GetAllAsync(); - query = query.Where(x => x.DateOfBirth >= dateFrom.Date); - query = query.Where(x => x.DateOfBirth <= dateTo.Date); + Task DeleteUserAsync(Guid id); - return await query.Select(x => new UserReport - { - FirstName = x.FirstName, - LastName = x.LastName, - }).ToListAsync(); + Task UpdateFirstNameByIdAsync(Guid id, string firstName); } - - public async Task> GetUserReportsAutoMap(DateTime dateFrom, DateTime dateTo) + public class UserReport { - var query = _userRepository.GetQueryable(); - - query = query.Where(x => x.DateOfBirth >= dateFrom.Date); - query = query.Where(x => x.DateOfBirth <= dateTo.Date); - - return await query.ProjectTo().ToListAsync(); + public string FirstName { get; set; } + public string LastName { get; set; } } - } - - public interface IUserRepository - { - IQueryable GetQueryable(); - - Task CreateUser(UserEntity user); - - Task> GetAll(); - IAsyncEnumerable GetAllAsync(); - } - - - public class UserReport - { - public string FirstName { get; set; } - public string LastName { get; set; } - } - - public class UserEntity - { - public Guid Id { get; set; } - public string FirstName { get; set; } - public string LastName { get; set; } - public DateTime DateOfBirth { get; set; } - } + public class UserEntity + { + public Guid Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public DateTime DateOfBirth { get; set; } + } } \ No newline at end of file diff --git a/src/MockQueryable/MockQueryable.Sample/MyServiceMoqTests.cs b/src/MockQueryable/MockQueryable.Sample/MyServiceMoqTests.cs index c7cec20..5ce65b4 100644 --- a/src/MockQueryable/MockQueryable.Sample/MyServiceMoqTests.cs +++ b/src/MockQueryable/MockQueryable.Sample/MyServiceMoqTests.cs @@ -1,30 +1,30 @@ -using System; +using Microsoft.EntityFrameworkCore; +using MockQueryable.Moq; +using Moq; +using NUnit.Framework; +using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Threading; using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using MockQueryable.Moq; -using Moq; -using NUnit.Framework; namespace MockQueryable.Sample { [TestFixture] - public class MyServiceMoqTests - { - private static readonly CultureInfo UsCultureInfo = new CultureInfo("en-US"); - - [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] - [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] - [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] - public void CreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) + public class MyServiceMoqTests { - //arrange - var userRepository = new Mock(); - var service = new MyService(userRepository.Object); - var users = new List + private static readonly CultureInfo UsCultureInfo = new CultureInfo("en-US"); + + [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] + [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] + [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] + public void CreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) + { + //arrange + var userRepository = new Mock(); + var service = new MyService(userRepository.Object); + var users = new List { new UserEntity {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, new UserEntity {FirstName = "ExistFirstName"}, @@ -32,64 +32,64 @@ public void CreateUserIfNotExist(string firstName, string lastName, DateTime dat new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)} }; - //expect - var mock = users.BuildMock(); - userRepository.Setup(x => x.GetQueryable()).Returns(mock); - //act - var ex = Assert.ThrowsAsync(() => - service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); - //assert - Assert.AreEqual(expectedError, ex.Message); - } + //expect + var mock = users.BuildMock(); + userRepository.Setup(x => x.GetQueryable()).Returns(mock); + //act + var ex = Assert.ThrowsAsync(() => + service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); + //assert + Assert.AreEqual(expectedError, ex.Message); + } - [TestCase("01/20/2012", "06/20/2018", 5)] - [TestCase("01/20/2012", "06/20/2012", 4)] - [TestCase("01/20/2012", "02/20/2012", 3)] - [TestCase("01/20/2010", "02/20/2011", 0)] - public async Task GetUserReports(DateTime from, DateTime to, int expectedCount) - { - //arrange - var userRepository = new Mock(); - var service = new MyService(userRepository.Object); - var users = CreateUserList(); - //expect - var mock = users.BuildMock(); - userRepository.Setup(x => x.GetQueryable()).Returns(mock); - //act - var result = await service.GetUserReports(from, to); - //assert - Assert.AreEqual(expectedCount, result.Count); - } + [TestCase("01/20/2012", "06/20/2018", 5)] + [TestCase("01/20/2012", "06/20/2012", 4)] + [TestCase("01/20/2012", "02/20/2012", 3)] + [TestCase("01/20/2010", "02/20/2011", 0)] + public async Task GetUserReports(DateTime from, DateTime to, int expectedCount) + { + //arrange + var userRepository = new Mock(); + var service = new MyService(userRepository.Object); + var users = CreateUserList(); + //expect + var mock = users.BuildMock(); + userRepository.Setup(x => x.GetQueryable()).Returns(mock); + //act + var result = await service.GetUserReports(from, to); + //assert + Assert.AreEqual(expectedCount, result.Count); + } - [TestCase("01/20/2012", "06/20/2018", 5)] - [TestCase("01/20/2012", "06/20/2012", 4)] - [TestCase("01/20/2012", "02/20/2012", 3)] - [TestCase("01/20/2010", "02/20/2011", 0)] - public async Task GetUserReports_AutoMap(DateTime from, DateTime to, int expectedCount) - { - //arrange - var userRepository = new Mock(); - var service = new MyService(userRepository.Object); - var users = CreateUserList(); - //expect - var mock = users.BuildMock(); - userRepository.Setup(x => x.GetQueryable()).Returns(mock); - //act - var result = await service.GetUserReportsAutoMap(from, to); - //assert - Assert.AreEqual(expectedCount, result.Count); - } + [TestCase("01/20/2012", "06/20/2018", 5)] + [TestCase("01/20/2012", "06/20/2012", 4)] + [TestCase("01/20/2012", "02/20/2012", 3)] + [TestCase("01/20/2010", "02/20/2011", 0)] + public async Task GetUserReports_AutoMap(DateTime from, DateTime to, int expectedCount) + { + //arrange + var userRepository = new Mock(); + var service = new MyService(userRepository.Object); + var users = CreateUserList(); + //expect + var mock = users.BuildMock(); + userRepository.Setup(x => x.GetQueryable()).Returns(mock); + //act + var result = await service.GetUserReportsAutoMap(from, to); + //assert + Assert.AreEqual(expectedCount, result.Count); + } - [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] - [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] - [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] - public void DbSetCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) - { - //arrange - var users = new List + [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] + [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] + [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] + public void DbSetCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) + { + //arrange + var users = new List { new UserEntity {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, new UserEntity {FirstName = "ExistFirstName"}, @@ -97,23 +97,23 @@ public void DbSetCreateUserIfNotExist(string firstName, string lastName, DateTim new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)} }; - var mock = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock.Object); - var service = new MyService(userRepository); - //act - var ex = Assert.ThrowsAsync(() => - service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); - //assert - Assert.AreEqual(expectedError, ex.Message); - } + var mock = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock.Object); + var service = new MyService(userRepository); + //act + var ex = Assert.ThrowsAsync(() => + service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); + //assert + Assert.AreEqual(expectedError, ex.Message); + } - [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] - [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] - [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] - public void DbSetCreatedFromCollectionCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) - { - //arrange - var users = new List + [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] + [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] + [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] + public void DbSetCreatedFromCollectionCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) + { + //arrange + var users = new List { new UserEntity {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, new UserEntity {FirstName = "ExistFirstName"}, @@ -121,122 +121,122 @@ public void DbSetCreatedFromCollectionCreateUserIfNotExist(string firstName, str new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)} }; - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock.Object); - var service = new MyService(userRepository); - //act - var ex = Assert.ThrowsAsync(() => - service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); - //assert - Assert.AreEqual(expectedError, ex.Message); - } + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock.Object); + var service = new MyService(userRepository); + //act + var ex = Assert.ThrowsAsync(() => + service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); + //assert + Assert.AreEqual(expectedError, ex.Message); + } [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] - public async Task DbSetCreateUser(string firstName, string lastName, DateTime dateOfBirth) - { - //arrange - var userEntities = new List(); - var mock = userEntities.AsQueryable().BuildMockDbSet(); + public async Task DbSetCreateUser(string firstName, string lastName, DateTime dateOfBirth) + { + //arrange + var userEntities = new List(); + var mock = userEntities.AsQueryable().BuildMockDbSet(); - mock.Setup(set => set.AddAsync(It.IsAny(), It.IsAny())) - .Callback((UserEntity entity, CancellationToken _) => userEntities.Add(entity)); + mock.Setup(set => set.AddAsync(It.IsAny(), It.IsAny())) + .Callback((UserEntity entity, CancellationToken _) => userEntities.Add(entity)); var userRepository = new TestDbSetRepository(mock.Object); - var service = new MyService(userRepository); - //act - await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); - // assert - var entity = mock.Object.Single(); - Assert.AreEqual(firstName, entity.FirstName); - Assert.AreEqual(lastName, entity.LastName); - Assert.AreEqual(dateOfBirth, entity.DateOfBirth); - } + var service = new MyService(userRepository); + //act + await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); + // assert + var entity = mock.Object.Single(); + Assert.AreEqual(firstName, entity.FirstName); + Assert.AreEqual(lastName, entity.LastName); + Assert.AreEqual(dateOfBirth, entity.DateOfBirth); + } - [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] - public async Task DbSetCreatedFromCollectionCreateUser(string firstName, string lastName, DateTime dateOfBirth) - { - //arrange - var userEntities = new List(); - var mock = userEntities.BuildMockDbSet(); - - mock.Setup(set => set.AddAsync(It.IsAny(), It.IsAny())) - .Callback((UserEntity entity, CancellationToken _) => userEntities.Add(entity)); - var userRepository = new TestDbSetRepository(mock.Object); - var service = new MyService(userRepository); - //act - await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); - // assert - var entity = mock.Object.Single(); - Assert.AreEqual(firstName, entity.FirstName); - Assert.AreEqual(lastName, entity.LastName); - Assert.AreEqual(dateOfBirth, entity.DateOfBirth); - } + [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] + public async Task DbSetCreatedFromCollectionCreateUser(string firstName, string lastName, DateTime dateOfBirth) + { + //arrange + var userEntities = new List(); + var mock = userEntities.BuildMockDbSet(); + + mock.Setup(set => set.AddAsync(It.IsAny(), It.IsAny())) + .Callback((UserEntity entity, CancellationToken _) => userEntities.Add(entity)); + var userRepository = new TestDbSetRepository(mock.Object); + var service = new MyService(userRepository); + //act + await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); + // assert + var entity = mock.Object.Single(); + Assert.AreEqual(firstName, entity.FirstName); + Assert.AreEqual(lastName, entity.LastName); + Assert.AreEqual(dateOfBirth, entity.DateOfBirth); + } [TestCase("01/20/2012", "06/20/2018", 5)] - [TestCase("01/20/2012", "06/20/2012", 4)] - [TestCase("01/20/2012", "02/20/2012", 3)] - [TestCase("01/20/2010", "02/20/2011", 0)] - public async Task DbSetGetUserReports(DateTime from, DateTime to, int expectedCount) - { - //arrange - var users = CreateUserList(); - var mock = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock.Object); - var service = new MyService(userRepository); - //act - var result = await service.GetUserReports(from, to); - //assert - Assert.AreEqual(expectedCount, result.Count); - } + [TestCase("01/20/2012", "06/20/2012", 4)] + [TestCase("01/20/2012", "02/20/2012", 3)] + [TestCase("01/20/2010", "02/20/2011", 0)] + public async Task DbSetGetUserReports(DateTime from, DateTime to, int expectedCount) + { + //arrange + var users = CreateUserList(); + var mock = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock.Object); + var service = new MyService(userRepository); + //act + var result = await service.GetUserReports(from, to); + //assert + Assert.AreEqual(expectedCount, result.Count); + } - [TestCase("01/20/2012", "06/20/2018", 5)] - [TestCase("01/20/2012", "06/20/2012", 4)] - [TestCase("01/20/2012", "02/20/2012", 3)] - [TestCase("01/20/2010", "02/20/2011", 0)] - public async Task DbSetCreatedFromCollectionGetUserReports(DateTime from, DateTime to, int expectedCount) - { - //arrange - var users = CreateUserList(); - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock.Object); - var service = new MyService(userRepository); - //act - var result = await service.GetUserReports(from, to); - //assert - Assert.AreEqual(expectedCount, result.Count); - } + [TestCase("01/20/2012", "06/20/2018", 5)] + [TestCase("01/20/2012", "06/20/2012", 4)] + [TestCase("01/20/2012", "02/20/2012", 3)] + [TestCase("01/20/2010", "02/20/2011", 0)] + public async Task DbSetCreatedFromCollectionGetUserReports(DateTime from, DateTime to, int expectedCount) + { + //arrange + var users = CreateUserList(); + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock.Object); + var service = new MyService(userRepository); + //act + var result = await service.GetUserReports(from, to); + //assert + Assert.AreEqual(expectedCount, result.Count); + } [TestCase] - public async Task DbSetGetAllUserEntity() - { - //arrange - var users = CreateUserList(); - var mock = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock.Object); - //act - var result = await userRepository.GetAll(); - //assert - Assert.AreEqual(users.Count, result.Count); - } + public async Task DbSetGetAllUserEntity() + { + //arrange + var users = CreateUserList(); + var mock = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock.Object); + //act + var result = await userRepository.GetAll(); + //assert + Assert.AreEqual(users.Count, result.Count); + } - [TestCase] - public async Task DbSetCreatedFromCollectionGetAllUserEntity() - { - //arrange - var users = CreateUserList(); - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock.Object); - //act - var result = await userRepository.GetAll(); - //assert - Assert.AreEqual(users.Count, result.Count); - } + [TestCase] + public async Task DbSetCreatedFromCollectionGetAllUserEntity() + { + //arrange + var users = CreateUserList(); + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock.Object); + //act + var result = await userRepository.GetAll(); + //assert + Assert.AreEqual(users.Count, result.Count); + } [TestCase] - public async Task DbSetFindAsyncUserEntity() - { - //arrange - var userId = Guid.NewGuid(); - var users = new List + public async Task DbSetFindAsyncUserEntity() + { + //arrange + var userId = Guid.NewGuid(); + var users = new List { new UserEntity { @@ -270,29 +270,29 @@ public async Task DbSetFindAsyncUserEntity() } }; - var mock = users.AsQueryable().BuildMockDbSet(); - mock.Setup(x => x.FindAsync(It.IsAny())).ReturnsAsync((object[] ids) => - { - var id = (Guid) ids.First(); - return users.FirstOrDefault(x => x.Id == id); - }); - var userRepository = new TestDbSetRepository(mock.Object); + var mock = users.AsQueryable().BuildMockDbSet(); + mock.Setup(x => x.FindAsync(It.IsAny())).ReturnsAsync((object[] ids) => + { + var id = (Guid) ids.First(); + return users.FirstOrDefault(x => x.Id == id); + }); + var userRepository = new TestDbSetRepository(mock.Object); - //act - var result = await ((DbSet)userRepository.GetQueryable()).FindAsync(userId); + //act + var result = await ((DbSet)userRepository.GetQueryable()).FindAsync(userId); - //assert - Assert.IsNotNull(result); - Assert.AreEqual("FirstName3", result.FirstName); - } + //assert + Assert.IsNotNull(result); + Assert.AreEqual("FirstName3", result.FirstName); + } - [TestCase] - public async Task DbSetCreatedFromCollectionFindAsyncUserEntity() - { - //arrange - var userId = Guid.NewGuid(); - var users = new List + [TestCase] + public async Task DbSetCreatedFromCollectionFindAsyncUserEntity() + { + //arrange + var userId = Guid.NewGuid(); + var users = new List { new UserEntity { @@ -326,82 +326,136 @@ public async Task DbSetCreatedFromCollectionFindAsyncUserEntity() } }; - var mock = users.BuildMockDbSet(); - mock.Setup(x => x.FindAsync(It.IsAny())).ReturnsAsync((object[] ids) => + var mock = users.BuildMockDbSet(); + mock.Setup(x => x.FindAsync(It.IsAny())).ReturnsAsync((object[] ids) => + { + var id = (Guid)ids.First(); + return users.FirstOrDefault(x => x.Id == id); + }); + var userRepository = new TestDbSetRepository(mock.Object); + + //act + var result = await ((DbSet)userRepository.GetQueryable()).FindAsync(userId); + + //assert + Assert.IsNotNull(result); + Assert.AreEqual("FirstName3", result.FirstName); + } + + [TestCase] + public async Task DbSetGetAllUserEntitiesAsync() { - var id = (Guid)ids.First(); - return users.FirstOrDefault(x => x.Id == id); - }); - var userRepository = new TestDbSetRepository(mock.Object); + // arrange + var users = CreateUserList(); - //act - var result = await ((DbSet)userRepository.GetQueryable()).FindAsync(userId); + var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet.Object); + + // act + var result = await userRepository.GetAllAsync().ToListAsync(); + + // assert + Assert.AreEqual(users.Count, result.Count); + } - //assert - Assert.IsNotNull(result); - Assert.AreEqual("FirstName3", result.FirstName); - } [TestCase] - public async Task DbSetGetAllUserEntitiesAsync() - { - // arrange - var users = CreateUserList(); + public async Task DbSetToListAsyncAsync_ShouldReturnAllEntities_WhenSourceIsChanged() + { + // arrange + var users = new List(); - var mockDbSet = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet.Object); + var mockDbSet = users.AsQueryable().BuildMockDbSet(); - // act - var result = await userRepository.GetAllAsync().ToListAsync(); + // act + var result1 = await mockDbSet.Object.ToListAsync(); + users.AddRange(CreateUserList()); + var result2 = await mockDbSet.Object.ToListAsync(); - // assert - Assert.AreEqual(users.Count, result.Count); - } - - - [TestCase] - public async Task DbSetToListAsyncAsync_ShouldReturnAllEntities_WhenSourceIsChanged() - { - // arrange - var users = new List(); + // assert + Assert.AreEqual(0, result1.Count); + Assert.AreEqual(users.Count, result2.Count); + } - var mockDbSet = users.AsQueryable().BuildMockDbSet(); + [TestCase] + public async Task DbSetCreatedFromCollectionGetAllUserEntitiesAsync() + { + // arrange + var users = CreateUserList(); - // act - var result1 = await mockDbSet.Object.ToListAsync(); - users.AddRange(CreateUserList()); - var result2 = await mockDbSet.Object.ToListAsync(); + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet.Object); - // assert - Assert.AreEqual(0, result1.Count); - Assert.AreEqual(users.Count, result2.Count); - } + // act + var result = await userRepository.GetAllAsync().ToListAsync(); + // assert + Assert.AreEqual(users.Count, result.Count); + } + [TestCase] + public async Task DbSetCreatedFromCollectionExecuteDeleteAsync() + { + // arrange + var userId = Guid.NewGuid(); + var users = CreateUserList(userId); - [TestCase] - public async Task DbSetCreatedFromCollectionGetAllUserEntitiesAsync() - { - // arrange - var users = CreateUserList(); + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet.Object); - var mockDbSet = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet.Object); + var count = await userRepository.DeleteUserAsync(userId); + Assert.AreEqual(1, count); + } - // act - var result = await userRepository.GetAllAsync().ToListAsync(); + [TestCase] + public async Task DbSetCreatedFromCollectionExecuteDeleteAsync_ShouldReturnZero() + { + // arrange + var userId = Guid.NewGuid(); + var users = CreateUserList(userId); - // assert - Assert.AreEqual(users.Count, result.Count); - } + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet.Object); - private static List CreateUserList() => new List - { - new UserEntity { FirstName = "FirstName1", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, - new UserEntity { FirstName = "FirstName2", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, - new UserEntity { FirstName = "FirstName3", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, - new UserEntity { FirstName = "FirstName3", LastName = "LastName", DateOfBirth = DateTime.Parse("03/20/2012", UsCultureInfo.DateTimeFormat) }, - new UserEntity { FirstName = "FirstName5", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2018", UsCultureInfo.DateTimeFormat) }, - }; - } + var count = await userRepository.DeleteUserAsync(Guid.NewGuid()); + Assert.AreEqual(0, count); + } + + [TestCase] + public async Task DbSetCreatedFromCollectionExecuteUpdateAsync() + { + // arrange + var userId = Guid.NewGuid(); + var users = CreateUserList(userId); + + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet.Object); + + var count = await userRepository.UpdateFirstNameByIdAsync(userId, "Unit Test"); + Assert.AreEqual(1, count); + } + + [TestCase] + public async Task DbSetCreatedFromCollectionExecuteUpdateAsync_ShouldReturnZero() + { + // arrange + var userId = Guid.NewGuid(); + var users = CreateUserList(userId); + + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet.Object); + + var count = await userRepository.UpdateFirstNameByIdAsync(Guid.NewGuid(), "Unit Test"); + Assert.AreEqual(0, count); + } + + private static List CreateUserList(Guid? userId = null) => new List + { + new UserEntity { Id = userId ?? Guid.NewGuid(), FirstName = "FirstName1", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, + new UserEntity { Id = Guid.NewGuid(), FirstName = "FirstName2", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, + new UserEntity { Id = Guid.NewGuid(), FirstName = "FirstName3", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, + new UserEntity { Id = Guid.NewGuid(), FirstName = "FirstName3", LastName = "LastName", DateOfBirth = DateTime.Parse("03/20/2012", UsCultureInfo.DateTimeFormat) }, + new UserEntity { Id = Guid.NewGuid(), FirstName = "FirstName5", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2018", UsCultureInfo.DateTimeFormat) }, + }; + } } \ No newline at end of file diff --git a/src/MockQueryable/MockQueryable.Sample/TestDbSetRepository.cs b/src/MockQueryable/MockQueryable.Sample/TestDbSetRepository.cs index 59266d0..b1f8fec 100644 --- a/src/MockQueryable/MockQueryable.Sample/TestDbSetRepository.cs +++ b/src/MockQueryable/MockQueryable.Sample/TestDbSetRepository.cs @@ -1,4 +1,5 @@ using Microsoft.EntityFrameworkCore; +using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; @@ -31,5 +32,17 @@ public IAsyncEnumerable GetAllAsync() { return _dbSet.AsAsyncEnumerable(); } + + public async Task DeleteUserAsync(Guid id) + { + return await _dbSet.Where(x => x.Id == id) + .ExecuteDeleteAsync(); + } + + public async Task UpdateFirstNameByIdAsync(Guid id, string firstName) + { + return await _dbSet.Where(x => x.Id == id) + .ExecuteUpdateAsync(opt => opt.SetProperty(x => x.FirstName, firstName)); + } } } \ No newline at end of file From 9d932f157c888aa2d24d2eb95fb053fe5be684b4 Mon Sep 17 00:00:00 2001 From: Raman Tsitou Date: Tue, 24 Sep 2024 09:52:39 +0200 Subject: [PATCH 2/8] Some architectural changes + additional tests for NSubstitude and FakeItEasy --- .../MockQueryable.Core/TestQueryProvider.cs | 16 +-- .../MockQueryable.EntityFrameworkCore.csproj | 1 + .../TestQueryProviderEfCore.cs | 16 +++ .../MyServiceFakeItEasyTests.cs | 116 +++++++++++++----- .../MockQueryable.Sample/MyServiceMoqTests.cs | 37 ++++-- .../MyServiceNSubstituteTests.cs | 96 +++++++++++++-- 6 files changed, 210 insertions(+), 72 deletions(-) diff --git a/src/MockQueryable/MockQueryable.Core/TestQueryProvider.cs b/src/MockQueryable/MockQueryable.Core/TestQueryProvider.cs index c5e2db2..4151f07 100644 --- a/src/MockQueryable/MockQueryable.Core/TestQueryProvider.cs +++ b/src/MockQueryable/MockQueryable.Core/TestQueryProvider.cs @@ -8,9 +8,6 @@ namespace MockQueryable.Core { public abstract class TestQueryProvider : IOrderedQueryable, IQueryProvider { - // Hardcoding this constants to avoid the reference to EFCore - private const string EF_EXECUTE_UPDATE_METHOD_NAME = "ExecuteUpdate"; - private const string EF_EXECUTE_DELETE_METHOD_NAME = "ExecuteDelete"; private IEnumerable _enumerable; @@ -53,18 +50,9 @@ public object Execute(Expression expression) return CompileExpressionItem(expression); } - public TResult Execute(Expression expression) + public virtual TResult Execute(Expression expression) { - if (expression is MethodCallExpression methodCall && (methodCall.Method.Name == EF_EXECUTE_UPDATE_METHOD_NAME || methodCall.Method.Name == EF_EXECUTE_DELETE_METHOD_NAME) - && typeof(TResult) == typeof(int)) - { - // Intercept ExecuteDelete and ExecuteUpdate calls - var affectedItems = CompileExpressionItem>(Expression).ToList(); - // Return the count of affected items - return (TResult)(object)affectedItems.Count; - } - // Fall back to default expression execution return CompileExpressionItem(expression); } @@ -86,7 +74,7 @@ IEnumerator IEnumerable.GetEnumerator() public IQueryProvider Provider => this; - private static TResult CompileExpressionItem(Expression expression) + protected static TResult CompileExpressionItem(Expression expression) { var visitor = new TestExpressionVisitor(); var body = visitor.Visit(expression); diff --git a/src/MockQueryable/MockQueryable.EntityFrameworkCore/MockQueryable.EntityFrameworkCore.csproj b/src/MockQueryable/MockQueryable.EntityFrameworkCore/MockQueryable.EntityFrameworkCore.csproj index 7a6ff19..a7ae9e2 100644 --- a/src/MockQueryable/MockQueryable.EntityFrameworkCore/MockQueryable.EntityFrameworkCore.csproj +++ b/src/MockQueryable/MockQueryable.EntityFrameworkCore/MockQueryable.EntityFrameworkCore.csproj @@ -46,6 +46,7 @@ + diff --git a/src/MockQueryable/MockQueryable.EntityFrameworkCore/TestQueryProviderEfCore.cs b/src/MockQueryable/MockQueryable.EntityFrameworkCore/TestQueryProviderEfCore.cs index 9b637ba..7da4937 100644 --- a/src/MockQueryable/MockQueryable.EntityFrameworkCore/TestQueryProviderEfCore.cs +++ b/src/MockQueryable/MockQueryable.EntityFrameworkCore/TestQueryProviderEfCore.cs @@ -3,6 +3,7 @@ using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Query; using MockQueryable.Core; @@ -32,6 +33,21 @@ public TResult ExecuteAsync(Expression expression, CancellationToken ca .Invoke(null, new[] { executionResult }); } + public override TResult Execute(Expression expression) + { + if (expression is MethodCallExpression methodCall && (methodCall.Method.Name == nameof(RelationalQueryableExtensions.ExecuteUpdate) || methodCall.Method.Name == nameof(RelationalQueryableExtensions.ExecuteDelete) ) + && typeof(TResult) == typeof(int)) + { + // Intercept ExecuteDelete and ExecuteUpdate calls + var affectedItems = base.Execute>(Expression).ToList(); + + // Return the count of affected items + return (TResult)(object)affectedItems.Count; + } + // Fall back to default expression execution + return base.Execute(expression); + } + public IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) { return new TestAsyncEnumerator(this.AsEnumerable().GetEnumerator()); diff --git a/src/MockQueryable/MockQueryable.Sample/MyServiceFakeItEasyTests.cs b/src/MockQueryable/MockQueryable.Sample/MyServiceFakeItEasyTests.cs index e74d2ee..c32a12f 100644 --- a/src/MockQueryable/MockQueryable.Sample/MyServiceFakeItEasyTests.cs +++ b/src/MockQueryable/MockQueryable.Sample/MyServiceFakeItEasyTests.cs @@ -135,7 +135,7 @@ public void DbSetCreatedFromCollectionCreateUserIfNotExist(string firstName, str } - [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] + [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] public async Task DbSetCreateUser(string firstName, string lastName, DateTime dateOfBirth) { //arrange @@ -181,7 +181,7 @@ public async Task DbSetCreatedFromCollectionCreateUser1(string firstName, string Assert.AreEqual(dateOfBirth, entity.DateOfBirth); } - [TestCase("01/20/2012", "06/20/2018", 5)] + [TestCase("01/20/2012", "06/20/2018", 5)] [TestCase("01/20/2012", "06/20/2012", 4)] [TestCase("01/20/2012", "02/20/2012", 3)] [TestCase("01/20/2010", "02/20/2011", 0)] @@ -215,7 +215,7 @@ public async Task DbSetCreatedFromCollectionGetUserReports(DateTime from, DateTi Assert.AreEqual(expectedCount, result.Count); } - [TestCase] + [Test] public async Task DbSetGetAllUserEntitiesAsync() { // arrange @@ -231,7 +231,7 @@ public async Task DbSetGetAllUserEntitiesAsync() Assert.AreEqual(users.Count, result.Count); } - [TestCase] + [Test] public async Task DbSetCreatedFromCollectionGetAllUserEntitiesAsync() { // arrange @@ -247,7 +247,7 @@ public async Task DbSetCreatedFromCollectionGetAllUserEntitiesAsync() Assert.AreEqual(users.Count, result.Count); } - [TestCase] + [Test] public async Task DbSetToListAsyncAsync_ShouldReturnAllEntities_WhenSourceIsChanged() { // arrange @@ -265,7 +265,7 @@ public async Task DbSetToListAsyncAsync_ShouldReturnAllEntities_WhenSourceIsChan Assert.AreEqual(users.Count, result2.Count); } - [TestCase] + [Test] public async Task DbSetGetAllUserEntity() { //arrange @@ -278,7 +278,7 @@ public async Task DbSetGetAllUserEntity() Assert.AreEqual(users.Count, result.Count); } - [TestCase] + [Test] public async Task DbSetCreatedFromCollectionGetAllUserEntity() { //arrange @@ -291,33 +291,83 @@ public async Task DbSetCreatedFromCollectionGetAllUserEntity() Assert.AreEqual(users.Count, result.Count); } - private static List CreateUserList() => new List + + [Test] + public async Task DbSetCreatedFromCollectionExecuteDeleteAsync() { - new UserEntity - { - FirstName = "FirstName1", LastName = "LastName", - DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) - }, - new UserEntity - { - FirstName = "FirstName2", LastName = "LastName", - DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) - }, - new UserEntity - { - FirstName = "FirstName3", LastName = "LastName", - DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) - }, - new UserEntity - { - FirstName = "FirstName3", LastName = "LastName", - DateOfBirth = DateTime.Parse("03/20/2012", UsCultureInfo.DateTimeFormat) - }, - new UserEntity - { - FirstName = "FirstName5", LastName = "LastName", - DateOfBirth = DateTime.Parse("01/20/2018", UsCultureInfo.DateTimeFormat) - }, + // arrange + var userId = Guid.NewGuid(); + var users = CreateUserList(userId); + + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); + + // act + var count = await userRepository.DeleteUserAsync(userId); + + // assert + Assert.AreEqual(1, count); + + } + + [Test] + public async Task DbSetCreatedFromCollectionExecuteDeleteAsync_ShouldReturnZero() + { + // arrange + var userId = Guid.NewGuid(); + var users = CreateUserList(userId); + + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); + + //act + var count = await userRepository.DeleteUserAsync(Guid.NewGuid()); + + // assert + Assert.AreEqual(0, count); + } + + [Test] + public async Task DbSetCreatedFromCollectionExecuteUpdateAsync() + { + // arrange + var userId = Guid.NewGuid(); + var users = CreateUserList(userId); + + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); + + //act + var count = await userRepository.UpdateFirstNameByIdAsync(userId, "Unit Test"); + + //assert + Assert.AreEqual(1, count); + } + + [Test] + public async Task DbSetCreatedFromCollectionExecuteUpdateAsync_ShouldReturnZero() + { + // arrange + var userId = Guid.NewGuid(); + var users = CreateUserList(userId); + + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); + + //act + var count = await userRepository.UpdateFirstNameByIdAsync(Guid.NewGuid(), "Unit Test"); + + //assert + Assert.AreEqual(0, count); + } + + private static List CreateUserList(Guid? userId = null) => new List + { + new UserEntity { Id = userId ?? Guid.NewGuid(), FirstName = "FirstName1", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, + new UserEntity { Id = Guid.NewGuid(), FirstName = "FirstName2", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, + new UserEntity { Id = Guid.NewGuid(), FirstName = "FirstName3", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, + new UserEntity { Id = Guid.NewGuid(), FirstName = "FirstName3", LastName = "LastName", DateOfBirth = DateTime.Parse("03/20/2012", UsCultureInfo.DateTimeFormat) }, + new UserEntity { Id = Guid.NewGuid(), FirstName = "FirstName5", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2018", UsCultureInfo.DateTimeFormat) }, }; diff --git a/src/MockQueryable/MockQueryable.Sample/MyServiceMoqTests.cs b/src/MockQueryable/MockQueryable.Sample/MyServiceMoqTests.cs index 5ce65b4..e1b0931 100644 --- a/src/MockQueryable/MockQueryable.Sample/MyServiceMoqTests.cs +++ b/src/MockQueryable/MockQueryable.Sample/MyServiceMoqTests.cs @@ -205,7 +205,7 @@ public async Task DbSetCreatedFromCollectionGetUserReports(DateTime from, DateTi Assert.AreEqual(expectedCount, result.Count); } - [TestCase] + [Test] public async Task DbSetGetAllUserEntity() { //arrange @@ -218,7 +218,7 @@ public async Task DbSetGetAllUserEntity() Assert.AreEqual(users.Count, result.Count); } - [TestCase] + [Test] public async Task DbSetCreatedFromCollectionGetAllUserEntity() { //arrange @@ -231,7 +231,7 @@ public async Task DbSetCreatedFromCollectionGetAllUserEntity() Assert.AreEqual(users.Count, result.Count); } - [TestCase] + [Test] public async Task DbSetFindAsyncUserEntity() { //arrange @@ -287,7 +287,7 @@ public async Task DbSetFindAsyncUserEntity() } - [TestCase] + [Test] public async Task DbSetCreatedFromCollectionFindAsyncUserEntity() { //arrange @@ -342,7 +342,7 @@ public async Task DbSetCreatedFromCollectionFindAsyncUserEntity() Assert.AreEqual("FirstName3", result.FirstName); } - [TestCase] + [Test] public async Task DbSetGetAllUserEntitiesAsync() { // arrange @@ -359,7 +359,7 @@ public async Task DbSetGetAllUserEntitiesAsync() } - [TestCase] + [Test] public async Task DbSetToListAsyncAsync_ShouldReturnAllEntities_WhenSourceIsChanged() { // arrange @@ -377,7 +377,7 @@ public async Task DbSetToListAsyncAsync_ShouldReturnAllEntities_WhenSourceIsChan Assert.AreEqual(users.Count, result2.Count); } - [TestCase] + [Test] public async Task DbSetCreatedFromCollectionGetAllUserEntitiesAsync() { // arrange @@ -393,7 +393,7 @@ public async Task DbSetCreatedFromCollectionGetAllUserEntitiesAsync() Assert.AreEqual(users.Count, result.Count); } - [TestCase] + [Test] public async Task DbSetCreatedFromCollectionExecuteDeleteAsync() { // arrange @@ -403,11 +403,15 @@ public async Task DbSetCreatedFromCollectionExecuteDeleteAsync() var mockDbSet = users.BuildMockDbSet(); var userRepository = new TestDbSetRepository(mockDbSet.Object); + // act var count = await userRepository.DeleteUserAsync(userId); + + // assert Assert.AreEqual(1, count); + } - [TestCase] + [Test] public async Task DbSetCreatedFromCollectionExecuteDeleteAsync_ShouldReturnZero() { // arrange @@ -417,11 +421,14 @@ public async Task DbSetCreatedFromCollectionExecuteDeleteAsync_ShouldReturnZero( var mockDbSet = users.BuildMockDbSet(); var userRepository = new TestDbSetRepository(mockDbSet.Object); + //act var count = await userRepository.DeleteUserAsync(Guid.NewGuid()); + + // assert Assert.AreEqual(0, count); } - [TestCase] + [Test] public async Task DbSetCreatedFromCollectionExecuteUpdateAsync() { // arrange @@ -430,12 +437,15 @@ public async Task DbSetCreatedFromCollectionExecuteUpdateAsync() var mockDbSet = users.BuildMockDbSet(); var userRepository = new TestDbSetRepository(mockDbSet.Object); - + + //act var count = await userRepository.UpdateFirstNameByIdAsync(userId, "Unit Test"); + + //assert Assert.AreEqual(1, count); } - [TestCase] + [Test] public async Task DbSetCreatedFromCollectionExecuteUpdateAsync_ShouldReturnZero() { // arrange @@ -445,7 +455,10 @@ public async Task DbSetCreatedFromCollectionExecuteUpdateAsync_ShouldReturnZero( var mockDbSet = users.BuildMockDbSet(); var userRepository = new TestDbSetRepository(mockDbSet.Object); + //act var count = await userRepository.UpdateFirstNameByIdAsync(Guid.NewGuid(), "Unit Test"); + + //assert Assert.AreEqual(0, count); } diff --git a/src/MockQueryable/MockQueryable.Sample/MyServiceNSubstituteTests.cs b/src/MockQueryable/MockQueryable.Sample/MyServiceNSubstituteTests.cs index 1f9e08c..d7f75fc 100644 --- a/src/MockQueryable/MockQueryable.Sample/MyServiceNSubstituteTests.cs +++ b/src/MockQueryable/MockQueryable.Sample/MyServiceNSubstituteTests.cs @@ -224,7 +224,7 @@ public async Task DbSetCreatedFromCollectionGetUserReports(DateTime from, DateTi Assert.AreEqual(expectedCount, result.Count); } - [TestCase] + [Test] public async Task DbSetGetAllUserEntity() { //arrange @@ -237,7 +237,7 @@ public async Task DbSetGetAllUserEntity() Assert.AreEqual(users.Count, result.Count); } - [TestCase] + [Test] public async Task DbSetCreatedFromCollectionGetAllUserEntity() { //arrange @@ -250,7 +250,7 @@ public async Task DbSetCreatedFromCollectionGetAllUserEntity() Assert.AreEqual(users.Count, result.Count); } - [TestCase] + [Test] public async Task DbSetGetAllUserEntitiesAsync() { // arrange @@ -267,7 +267,7 @@ public async Task DbSetGetAllUserEntitiesAsync() } - [TestCase] + [Test] public async Task DbSetGetAllUserEntitiesAsync_ShouldReturnAllEntities_WhenSourceIsChanged() { // arrange @@ -286,7 +286,7 @@ public async Task DbSetGetAllUserEntitiesAsync_ShouldReturnAllEntities_WhenSourc Assert.AreEqual(users.Count, result2.Count); } - [TestCase] + [Test] public async Task DbSetCreatedFromCollectionGetAllUserEntitiesAsync() { // arrange @@ -302,7 +302,7 @@ public async Task DbSetCreatedFromCollectionGetAllUserEntitiesAsync() Assert.AreEqual(users.Count, result.Count); } - [TestCase] + [Test] public async Task DbSetGetOneUserTntityAsync() { // arrange @@ -320,7 +320,7 @@ public async Task DbSetGetOneUserTntityAsync() Assert.AreEqual(users.First(), result); } - [TestCase] + [Test] public async Task DbSetCreatedFromCollectionGetOneUserTntityAsync() { // arrange @@ -338,13 +338,83 @@ public async Task DbSetCreatedFromCollectionGetOneUserTntityAsync() Assert.AreEqual(users.First(), result); } - private static List CreateUserList() => new List + + [Test] + public async Task DbSetCreatedFromCollectionExecuteDeleteAsync() + { + // arrange + var userId = Guid.NewGuid(); + var users = CreateUserList(userId); + + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); + + // act + var count = await userRepository.DeleteUserAsync(userId); + + // assert + Assert.AreEqual(1, count); + + } + + [Test] + public async Task DbSetCreatedFromCollectionExecuteDeleteAsync_ShouldReturnZero() + { + // arrange + var userId = Guid.NewGuid(); + var users = CreateUserList(userId); + + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); + + //act + var count = await userRepository.DeleteUserAsync(Guid.NewGuid()); + + // assert + Assert.AreEqual(0, count); + } + + [Test] + public async Task DbSetCreatedFromCollectionExecuteUpdateAsync() + { + // arrange + var userId = Guid.NewGuid(); + var users = CreateUserList(userId); + + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); + + //act + var count = await userRepository.UpdateFirstNameByIdAsync(userId, "Unit Test"); + + //assert + Assert.AreEqual(1, count); + } + + [Test] + public async Task DbSetCreatedFromCollectionExecuteUpdateAsync_ShouldReturnZero() + { + // arrange + var userId = Guid.NewGuid(); + var users = CreateUserList(userId); + + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); + + //act + var count = await userRepository.UpdateFirstNameByIdAsync(Guid.NewGuid(), "Unit Test"); + + //assert + Assert.AreEqual(0, count); + } + + private static List CreateUserList(Guid? userId = null) => new List { - new UserEntity { FirstName = "FirstName1", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, - new UserEntity { FirstName = "FirstName2", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, - new UserEntity { FirstName = "FirstName3", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, - new UserEntity { FirstName = "FirstName3", LastName = "LastName", DateOfBirth = DateTime.Parse("03/20/2012", UsCultureInfo.DateTimeFormat) }, - new UserEntity { FirstName = "FirstName5", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2018", UsCultureInfo.DateTimeFormat) }, + new UserEntity { Id = userId ?? Guid.NewGuid(), FirstName = "FirstName1", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, + new UserEntity { Id = Guid.NewGuid(), FirstName = "FirstName2", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, + new UserEntity { Id = Guid.NewGuid(), FirstName = "FirstName3", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, + new UserEntity { Id = Guid.NewGuid(), FirstName = "FirstName3", LastName = "LastName", DateOfBirth = DateTime.Parse("03/20/2012", UsCultureInfo.DateTimeFormat) }, + new UserEntity { Id = Guid.NewGuid(), FirstName = "FirstName5", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2018", UsCultureInfo.DateTimeFormat) }, }; } From 29a1348e284339899f3072a7c01eec70a35347da Mon Sep 17 00:00:00 2001 From: Raman Tsitou Date: Tue, 24 Sep 2024 10:01:40 +0200 Subject: [PATCH 3/8] v7.0.4-beta --- .../MockQueryable.Core/MockQueryable.Core.csproj | 8 ++++---- .../MockQueryable.EntityFrameworkCore.csproj | 8 ++++---- .../MockQueryable.FakeItEasy.csproj | 8 ++++---- .../MockQueryable.Moq/MockQueryable.Moq.csproj | 8 ++++---- .../MockQueryable.NSubstitute.csproj | 8 ++++---- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/MockQueryable/MockQueryable.Core/MockQueryable.Core.csproj b/src/MockQueryable/MockQueryable.Core/MockQueryable.Core.csproj index 55b5ba7..f19317f 100644 --- a/src/MockQueryable/MockQueryable.Core/MockQueryable.Core.csproj +++ b/src/MockQueryable/MockQueryable.Core/MockQueryable.Core.csproj @@ -14,11 +14,11 @@ Mock EntityFrameworkCore Queryable mock EF UnitTests EntityFrameworkCore true - #80 Altered namespace for extension method to revert a breaking change - Thanks @StevePy + #81 Add support to ExecuteDelete and ExecuteUpdate - Thanks @lazaro-ansaldi - 7.0.3 - 7.0.0.3 - 7.0.0.3 + 7.0.4-beta + 7.0.0.4 + 7.0.0.4 LICENSE README.md diff --git a/src/MockQueryable/MockQueryable.EntityFrameworkCore/MockQueryable.EntityFrameworkCore.csproj b/src/MockQueryable/MockQueryable.EntityFrameworkCore/MockQueryable.EntityFrameworkCore.csproj index a7ae9e2..883a758 100644 --- a/src/MockQueryable/MockQueryable.EntityFrameworkCore/MockQueryable.EntityFrameworkCore.csproj +++ b/src/MockQueryable/MockQueryable.EntityFrameworkCore/MockQueryable.EntityFrameworkCore.csproj @@ -15,11 +15,11 @@ Mock EntityFrameworkCore Queryable mock EF UnitTests EntityFrameworkCore true - #80 Altered namespace for extension method to revert a breaking change - Thanks @StevePy + #81 Add support to ExecuteDelete and ExecuteUpdate - Thanks @lazaro-ansaldi - 7.0.3 - 7.0.0.3 - 7.0.0.3 + 7.0.4-beta + 7.0.0.4 + 7.0.0.4 LICENSE README.md diff --git a/src/MockQueryable/MockQueryable.FakeItEasy/MockQueryable.FakeItEasy.csproj b/src/MockQueryable/MockQueryable.FakeItEasy/MockQueryable.FakeItEasy.csproj index dbfedb2..746f244 100644 --- a/src/MockQueryable/MockQueryable.FakeItEasy/MockQueryable.FakeItEasy.csproj +++ b/src/MockQueryable/MockQueryable.FakeItEasy/MockQueryable.FakeItEasy.csproj @@ -14,11 +14,11 @@ Mock EntityFrameworkCore Queryable mock EF EFCore UnitTests FakeItEasy true - #80 Altered namespace for extension method to revert a breaking change - Thanks @StevePy + #81 Add support to ExecuteDelete and ExecuteUpdate - Thanks @lazaro-ansaldi - 7.0.3 - 7.0.0.3 - 7.0.0.3 + 7.0.4-beta + 7.0.0.4 + 7.0.0.4 LICENSE README.md diff --git a/src/MockQueryable/MockQueryable.Moq/MockQueryable.Moq.csproj b/src/MockQueryable/MockQueryable.Moq/MockQueryable.Moq.csproj index c9c2fa6..e7d2f38 100644 --- a/src/MockQueryable/MockQueryable.Moq/MockQueryable.Moq.csproj +++ b/src/MockQueryable/MockQueryable.Moq/MockQueryable.Moq.csproj @@ -14,11 +14,11 @@ Mock EntityFrameworkCore Queryable mock EF EFCore UnitTests EntityFrameworkCore Moq true - #80 Altered namespace for extension method to revert a breaking change - Thanks @StevePy + #81 Add support to ExecuteDelete and ExecuteUpdate - Thanks @lazaro-ansaldi - 7.0.3 - 7.0.0.3 - 7.0.0.3 + 7.0.4-beta + 7.0.0.4 + 7.0.0.4 LICENSE README.md diff --git a/src/MockQueryable/MockQueryable.NSubstitute/MockQueryable.NSubstitute.csproj b/src/MockQueryable/MockQueryable.NSubstitute/MockQueryable.NSubstitute.csproj index 3266042..dfc0fe5 100644 --- a/src/MockQueryable/MockQueryable.NSubstitute/MockQueryable.NSubstitute.csproj +++ b/src/MockQueryable/MockQueryable.NSubstitute/MockQueryable.NSubstitute.csproj @@ -14,11 +14,11 @@ Mock EntityFrameworkCore Queryable mock EF EFCore UnitTests EntityFrameworkCore NSubstitute true - #80 Altered namespace for extension method to revert a breaking change - Thanks @StevePy + #81 Add support to ExecuteDelete and ExecuteUpdate - Thanks @lazaro-ansaldi - 7.0.3 - 7.0.0.3 - 7.0.0.3 + 7.0.4-beta + 7.0.0.4 + 7.0.0.4 LICENSE README.md From 086048a4216b4b5a1504c177245a79fe0adb55ba Mon Sep 17 00:00:00 2001 From: Catlandor Date: Fri, 18 Jul 2025 16:52:03 +0200 Subject: [PATCH 4/8] #82 Update NuGet packages --- .../MockQueryable.EntityFrameworkCore.csproj | 4 +- .../MockQueryable.FakeItEasy.csproj | 4 +- .../MockQueryable.Moq.csproj | 4 +- .../MockQueryable.NSubstitute.csproj | 4 +- .../MockQueryable.Sample.csproj | 12 +- .../MockQueryable.Sample/MyService.cs | 18 +- .../MyServiceFakeItEasyTests.cs | 242 +++---- .../MockQueryable.Sample/MyServiceMoqTests.cs | 242 ++++--- .../MyServiceNSubstituteTests.cs | 612 +++++++++--------- 9 files changed, 569 insertions(+), 573 deletions(-) diff --git a/src/MockQueryable/MockQueryable.EntityFrameworkCore/MockQueryable.EntityFrameworkCore.csproj b/src/MockQueryable/MockQueryable.EntityFrameworkCore/MockQueryable.EntityFrameworkCore.csproj index 88963b3..b1aaa83 100644 --- a/src/MockQueryable/MockQueryable.EntityFrameworkCore/MockQueryable.EntityFrameworkCore.csproj +++ b/src/MockQueryable/MockQueryable.EntityFrameworkCore/MockQueryable.EntityFrameworkCore.csproj @@ -1,7 +1,7 @@ - net6 + net8 MockQueryable.EntityFrameworkCore Roman Titov @@ -45,7 +45,7 @@ - + diff --git a/src/MockQueryable/MockQueryable.FakeItEasy/MockQueryable.FakeItEasy.csproj b/src/MockQueryable/MockQueryable.FakeItEasy/MockQueryable.FakeItEasy.csproj index dbfedb2..eea1d69 100644 --- a/src/MockQueryable/MockQueryable.FakeItEasy/MockQueryable.FakeItEasy.csproj +++ b/src/MockQueryable/MockQueryable.FakeItEasy/MockQueryable.FakeItEasy.csproj @@ -1,7 +1,7 @@  - net6 + net8 MockQueryable.FakeItEasy Roman Titov @@ -26,7 +26,7 @@ - + diff --git a/src/MockQueryable/MockQueryable.Moq/MockQueryable.Moq.csproj b/src/MockQueryable/MockQueryable.Moq/MockQueryable.Moq.csproj index c9c2fa6..55adeec 100644 --- a/src/MockQueryable/MockQueryable.Moq/MockQueryable.Moq.csproj +++ b/src/MockQueryable/MockQueryable.Moq/MockQueryable.Moq.csproj @@ -1,7 +1,7 @@  - net6 + net8 MockQueryable.Moq Roman Titov @@ -26,7 +26,7 @@ - + diff --git a/src/MockQueryable/MockQueryable.NSubstitute/MockQueryable.NSubstitute.csproj b/src/MockQueryable/MockQueryable.NSubstitute/MockQueryable.NSubstitute.csproj index 3266042..29fc678 100644 --- a/src/MockQueryable/MockQueryable.NSubstitute/MockQueryable.NSubstitute.csproj +++ b/src/MockQueryable/MockQueryable.NSubstitute/MockQueryable.NSubstitute.csproj @@ -1,7 +1,7 @@  - net6 + net8 MockQueryable.NSubstitute Roman Titov @@ -26,7 +26,7 @@ - + diff --git a/src/MockQueryable/MockQueryable.Sample/MockQueryable.Sample.csproj b/src/MockQueryable/MockQueryable.Sample/MockQueryable.Sample.csproj index 2ebe7d8..e2d3c68 100644 --- a/src/MockQueryable/MockQueryable.Sample/MockQueryable.Sample.csproj +++ b/src/MockQueryable/MockQueryable.Sample/MockQueryable.Sample.csproj @@ -1,18 +1,18 @@  - net6.0 + net8 - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/src/MockQueryable/MockQueryable.Sample/MyService.cs b/src/MockQueryable/MockQueryable.Sample/MyService.cs index 50d782b..eb402d5 100644 --- a/src/MockQueryable/MockQueryable.Sample/MyService.cs +++ b/src/MockQueryable/MockQueryable.Sample/MyService.cs @@ -5,19 +5,25 @@ using AutoMapper; using AutoMapper.QueryableExtensions; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; namespace MockQueryable.Sample { public class MyService { private readonly IUserRepository _userRepository; + private static readonly MapperConfiguration _mapperConfiguration = new MapperConfiguration( + cfg => + { + cfg.CreateMap() + .ForMember(dto => dto.FirstName, conf => conf.MapFrom(ol => ol.FirstName)) + .ForMember(dto => dto.LastName, conf => conf.MapFrom(ol => ol.LastName)); + }, + loggerFactory: new LoggerFactory()); public static void Initialize() { - Mapper.Initialize(cfg => cfg.CreateMap() - .ForMember(dto => dto.FirstName, conf => conf.MapFrom(ol => ol.FirstName)) - .ForMember(dto => dto.LastName, conf => conf.MapFrom(ol => ol.LastName))); - Mapper.Configuration.AssertConfigurationIsValid(); + _mapperConfiguration.AssertConfigurationIsValid(); } public MyService(IUserRepository userRepository) @@ -68,7 +74,6 @@ public async Task> GetUserReports(DateTime dateFrom, DateTime d }).ToListAsync(); } - public async Task> GetUserReportsAutoMap(DateTime dateFrom, DateTime dateTo) { var query = _userRepository.GetQueryable(); @@ -76,7 +81,7 @@ public async Task> GetUserReportsAutoMap(DateTime dateFrom, Dat query = query.Where(x => x.DateOfBirth >= dateFrom.Date); query = query.Where(x => x.DateOfBirth <= dateTo.Date); - return await query.ProjectTo().ToListAsync(); + return await query.ProjectTo(_mapperConfiguration).ToListAsync(); } } @@ -91,7 +96,6 @@ public interface IUserRepository IAsyncEnumerable GetAllAsync(); } - public class UserReport { public string FirstName { get; set; } diff --git a/src/MockQueryable/MockQueryable.Sample/MyServiceFakeItEasyTests.cs b/src/MockQueryable/MockQueryable.Sample/MyServiceFakeItEasyTests.cs index e74d2ee..4090dad 100644 --- a/src/MockQueryable/MockQueryable.Sample/MyServiceFakeItEasyTests.cs +++ b/src/MockQueryable/MockQueryable.Sample/MyServiceFakeItEasyTests.cs @@ -14,34 +14,35 @@ namespace MockQueryable.Sample [TestFixture] public class MyServiceFakeItEasyTests { - private static readonly CultureInfo UsCultureInfo = new CultureInfo("en-US"); + private static readonly CultureInfo UsCultureInfo = new("en-US"); [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] public void CreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) { - //arrange - + // arrange var userRepository = A.Fake(); var service = new MyService(userRepository); var users = new List { - new UserEntity {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, - new UserEntity {FirstName = "ExistFirstName"}, - new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, - new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, - new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {FirstName = "ExistFirstName"}, + new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, }; - //expect + + // expect var mock = users.BuildMock(); A.CallTo(() => userRepository.GetQueryable()).Returns(mock); - //act + + // act var ex = Assert.ThrowsAsync(() => service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); - //assert - Assert.AreEqual(expectedError, ex.Message); + // assert + Assert.That(expectedError, Is.EqualTo(ex.Message)); } [TestCase("01/20/2012", "06/20/2018", 5)] @@ -60,29 +61,28 @@ public async Task GetUserReports(DateTime from, DateTime to, int expectedCount) //act var result = await service.GetUserReports(from, to); //assert - Assert.AreEqual(expectedCount, result.Count); - + Assert.That(expectedCount, Is.EqualTo(result.Count)); } - [TestCase("01/20/2012", "06/20/2018", 5)] [TestCase("01/20/2012", "06/20/2012", 4)] [TestCase("01/20/2012", "02/20/2012", 3)] [TestCase("01/20/2010", "02/20/2011", 0)] public async Task GetUserReports_AutoMap(DateTime from, DateTime to, int expectedCount) { - //arrange + // arrange var userRepository = A.Fake(); var service = new MyService(userRepository); var users = CreateUserList(); - //expect + // expect var mock = users.BuildMock(); A.CallTo(() => userRepository.GetQueryable()).Returns(mock); - //act + + // act var result = await service.GetUserReportsAutoMap(from, to); - //assert - Assert.AreEqual(expectedCount, result.Count); + // assert + Assert.That(expectedCount, Is.EqualTo(result.Count)); } [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] @@ -90,24 +90,25 @@ public async Task GetUserReports_AutoMap(DateTime from, DateTime to, int expecte [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] public void DbSetCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) { - //arrange + // arrange var users = new List { - new UserEntity {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, - new UserEntity {FirstName = "ExistFirstName"}, - new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, - new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, - new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {FirstName = "ExistFirstName"}, + new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, }; var mock = users.AsQueryable().BuildMockDbSet(); var userRepository = new TestDbSetRepository(mock); var service = new MyService(userRepository); - //act + + // act var ex = Assert.ThrowsAsync(() => service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); - //assert - Assert.AreEqual(expectedError, ex.Message); + // assert + Assert.That(expectedError, Is.EqualTo(ex.Message)); } [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] @@ -115,87 +116,92 @@ public void DbSetCreateUserIfNotExist(string firstName, string lastName, DateTim [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] public void DbSetCreatedFromCollectionCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) { - //arrange - var users = new List + // arrange + var users = new List { - new UserEntity {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, - new UserEntity {FirstName = "ExistFirstName"}, - new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, - new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, - new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {FirstName = "ExistFirstName"}, + new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, }; - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - //act - var ex = Assert.ThrowsAsync(() => - service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); - //assert - Assert.AreEqual(expectedError, ex.Message); - + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + // act + var ex = Assert.ThrowsAsync(() => + service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); + // assert + Assert.That(expectedError, Is.EqualTo(ex.Message)); } - [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] + [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] public async Task DbSetCreateUser(string firstName, string lastName, DateTime dateOfBirth) { - //arrange + // arrange var userEntities = new List(); var mock = userEntities.AsQueryable().BuildMockDbSet(); A.CallTo(() => mock.AddAsync(A._, A._)) .ReturnsLazily(call => { - userEntities.Add((UserEntity) call.Arguments[0]); + userEntities.Add((UserEntity)call.Arguments[0]); return default; }); var userRepository = new TestDbSetRepository(mock); var service = new MyService(userRepository); - //act + + // act await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); + // assert var entity = mock.Single(); - Assert.AreEqual(firstName, entity.FirstName); - Assert.AreEqual(lastName, entity.LastName); - Assert.AreEqual(dateOfBirth, entity.DateOfBirth); + Assert.That(firstName, Is.EqualTo(entity.FirstName)); + Assert.That(lastName, Is.EqualTo(entity.LastName)); + Assert.That(dateOfBirth, Is.EqualTo(entity.DateOfBirth)); } [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] public async Task DbSetCreatedFromCollectionCreateUser1(string firstName, string lastName, DateTime dateOfBirth) { - //arrange - var userEntities = new List(); - var mock = userEntities.BuildMockDbSet(); - A.CallTo(() => mock.AddAsync(A._, A._)) - .ReturnsLazily(call => - { - userEntities.Add((UserEntity)call.Arguments[0]); - return default; - }); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - //act - await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); - // assert - var entity = mock.Single(); - Assert.AreEqual(firstName, entity.FirstName); - Assert.AreEqual(lastName, entity.LastName); - Assert.AreEqual(dateOfBirth, entity.DateOfBirth); + // arrange + var userEntities = new List(); + var mock = userEntities.BuildMockDbSet(); + A.CallTo(() => mock.AddAsync(A._, A._)) + .ReturnsLazily(call => + { + userEntities.Add((UserEntity)call.Arguments[0]); + return default; + }); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + + // act + await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); + + // assert + var entity = mock.Single(); + Assert.That(firstName, Is.EqualTo(entity.FirstName)); + Assert.That(lastName, Is.EqualTo(entity.LastName)); + Assert.That(dateOfBirth, Is.EqualTo(entity.DateOfBirth)); } - [TestCase("01/20/2012", "06/20/2018", 5)] + [TestCase("01/20/2012", "06/20/2018", 5)] [TestCase("01/20/2012", "06/20/2012", 4)] [TestCase("01/20/2012", "02/20/2012", 3)] [TestCase("01/20/2010", "02/20/2011", 0)] public async Task DbSetGetUserReports(DateTime from, DateTime to, int expectedCount) { - //arrange + // arrange var users = CreateUserList(); var mock = users.AsQueryable().BuildMockDbSet(); var userRepository = new TestDbSetRepository(mock); var service = new MyService(userRepository); - //act + + // act var result = await service.GetUserReports(from, to); - //assert - Assert.AreEqual(expectedCount, result.Count); + + // assert + Assert.That(expectedCount, Is.EqualTo(result.Count)); } [TestCase("01/20/2012", "06/20/2018", 5)] @@ -204,18 +210,20 @@ public async Task DbSetGetUserReports(DateTime from, DateTime to, int expectedCo [TestCase("01/20/2010", "02/20/2011", 0)] public async Task DbSetCreatedFromCollectionGetUserReports(DateTime from, DateTime to, int expectedCount) { - //arrange - var users = CreateUserList(); - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - //act - var result = await service.GetUserReports(from, to); - //assert - Assert.AreEqual(expectedCount, result.Count); + // arrange + var users = CreateUserList(); + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + + // act + var result = await service.GetUserReports(from, to); + + // assert + Assert.That(expectedCount, Is.EqualTo(result.Count)); } - [TestCase] + [TestCase] public async Task DbSetGetAllUserEntitiesAsync() { // arrange @@ -228,23 +236,23 @@ public async Task DbSetGetAllUserEntitiesAsync() var result = await userRepository.GetAllAsync().ToListAsync(); // assert - Assert.AreEqual(users.Count, result.Count); + Assert.That(users.Count, Is.EqualTo(result.Count)); } [TestCase] public async Task DbSetCreatedFromCollectionGetAllUserEntitiesAsync() { - // arrange - var users = CreateUserList(); + // arrange + var users = CreateUserList(); - var mockDbSet = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet); + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); - // act - var result = await userRepository.GetAllAsync().ToListAsync(); + // act + var result = await userRepository.GetAllAsync().ToListAsync(); - // assert - Assert.AreEqual(users.Count, result.Count); + // assert + Assert.That(users.Count, Is.EqualTo(result.Count)); } [TestCase] @@ -254,44 +262,48 @@ public async Task DbSetToListAsyncAsync_ShouldReturnAllEntities_WhenSourceIsChan var users = new List(); var mockDbSet = users.AsQueryable().BuildMockDbSet(); - + // act var result1 = await mockDbSet.ToListAsync(); users.AddRange(CreateUserList()); var result2 = await mockDbSet.ToListAsync(); // assert - Assert.AreEqual(0, result1.Count); - Assert.AreEqual(users.Count, result2.Count); + Assert.That(0, Is.EqualTo(result1.Count)); + Assert.That(users.Count, Is.EqualTo(result2.Count)); } [TestCase] public async Task DbSetGetAllUserEntity() { - //arrange - var users = CreateUserList(); - var mock = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - //act - var result = await userRepository.GetAll(); - //assert - Assert.AreEqual(users.Count, result.Count); + //arrange + var users = CreateUserList(); + var mock = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + + //act + var result = await userRepository.GetAll(); + + //assert + Assert.That(users.Count, Is.EqualTo(result.Count)); } [TestCase] public async Task DbSetCreatedFromCollectionGetAllUserEntity() { - //arrange - var users = CreateUserList(); - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - //act - var result = await userRepository.GetAll(); - //assert - Assert.AreEqual(users.Count, result.Count); + // arrange + var users = CreateUserList(); + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + + // act + var result = await userRepository.GetAll(); + + // assert + Assert.That(users.Count, Is.EqualTo(result.Count)); } - private static List CreateUserList() => new List + private static List CreateUserList() => new() { new UserEntity { @@ -319,7 +331,5 @@ public async Task DbSetCreatedFromCollectionGetAllUserEntity() DateOfBirth = DateTime.Parse("01/20/2018", UsCultureInfo.DateTimeFormat) }, }; - - } } diff --git a/src/MockQueryable/MockQueryable.Sample/MyServiceMoqTests.cs b/src/MockQueryable/MockQueryable.Sample/MyServiceMoqTests.cs index c7cec20..d597ac0 100644 --- a/src/MockQueryable/MockQueryable.Sample/MyServiceMoqTests.cs +++ b/src/MockQueryable/MockQueryable.Sample/MyServiceMoqTests.cs @@ -11,10 +11,10 @@ namespace MockQueryable.Sample { - [TestFixture] + [TestFixture] public class MyServiceMoqTests { - private static readonly CultureInfo UsCultureInfo = new CultureInfo("en-US"); + private static readonly CultureInfo UsCultureInfo = new("en-US"); [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] @@ -26,11 +26,11 @@ public void CreateUserIfNotExist(string firstName, string lastName, DateTime dat var service = new MyService(userRepository.Object); var users = new List { - new UserEntity {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, - new UserEntity {FirstName = "ExistFirstName"}, - new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, - new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, - new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)} + new() {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {FirstName = "ExistFirstName"}, + new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)} }; //expect var mock = users.BuildMock(); @@ -39,7 +39,7 @@ public void CreateUserIfNotExist(string firstName, string lastName, DateTime dat var ex = Assert.ThrowsAsync(() => service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); //assert - Assert.AreEqual(expectedError, ex.Message); + Assert.That(expectedError, Is.EqualTo(ex.Message)); } [TestCase("01/20/2012", "06/20/2018", 5)] @@ -58,7 +58,7 @@ public async Task GetUserReports(DateTime from, DateTime to, int expectedCount) //act var result = await service.GetUserReports(from, to); //assert - Assert.AreEqual(expectedCount, result.Count); + Assert.That(expectedCount, Is.EqualTo(result.Count)); } @@ -79,7 +79,7 @@ public async Task GetUserReports_AutoMap(DateTime from, DateTime to, int expecte //act var result = await service.GetUserReportsAutoMap(from, to); //assert - Assert.AreEqual(expectedCount, result.Count); + Assert.That(expectedCount, Is.EqualTo(result.Count)); } @@ -91,11 +91,11 @@ public void DbSetCreateUserIfNotExist(string firstName, string lastName, DateTim //arrange var users = new List { - new UserEntity {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, - new UserEntity {FirstName = "ExistFirstName"}, - new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, - new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, - new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)} + new() {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {FirstName = "ExistFirstName"}, + new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)} }; var mock = users.AsQueryable().BuildMockDbSet(); var userRepository = new TestDbSetRepository(mock.Object); @@ -104,7 +104,7 @@ public void DbSetCreateUserIfNotExist(string firstName, string lastName, DateTim var ex = Assert.ThrowsAsync(() => service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); //assert - Assert.AreEqual(expectedError, ex.Message); + Assert.That(expectedError, Is.EqualTo(ex.Message)); } [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] @@ -112,26 +112,26 @@ public void DbSetCreateUserIfNotExist(string firstName, string lastName, DateTim [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] public void DbSetCreatedFromCollectionCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) { - //arrange - var users = new List + //arrange + var users = new List { - new UserEntity {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, - new UserEntity {FirstName = "ExistFirstName"}, - new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, - new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, - new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)} + new() {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {FirstName = "ExistFirstName"}, + new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)} }; - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock.Object); - var service = new MyService(userRepository); - //act - var ex = Assert.ThrowsAsync(() => - service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); - //assert - Assert.AreEqual(expectedError, ex.Message); + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock.Object); + var service = new MyService(userRepository); + //act + var ex = Assert.ThrowsAsync(() => + service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); + //assert + Assert.That(expectedError, Is.EqualTo(ex.Message)); } - [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] + [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] public async Task DbSetCreateUser(string firstName, string lastName, DateTime dateOfBirth) { //arrange @@ -140,38 +140,38 @@ public async Task DbSetCreateUser(string firstName, string lastName, DateTime da mock.Setup(set => set.AddAsync(It.IsAny(), It.IsAny())) .Callback((UserEntity entity, CancellationToken _) => userEntities.Add(entity)); - var userRepository = new TestDbSetRepository(mock.Object); + var userRepository = new TestDbSetRepository(mock.Object); var service = new MyService(userRepository); //act await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); // assert var entity = mock.Object.Single(); - Assert.AreEqual(firstName, entity.FirstName); - Assert.AreEqual(lastName, entity.LastName); - Assert.AreEqual(dateOfBirth, entity.DateOfBirth); + Assert.That(firstName, Is.EqualTo(entity.FirstName)); + Assert.That(lastName, Is.EqualTo(entity.LastName)); + Assert.That(dateOfBirth, Is.EqualTo(entity.DateOfBirth)); } [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] public async Task DbSetCreatedFromCollectionCreateUser(string firstName, string lastName, DateTime dateOfBirth) { - //arrange - var userEntities = new List(); - var mock = userEntities.BuildMockDbSet(); - - mock.Setup(set => set.AddAsync(It.IsAny(), It.IsAny())) - .Callback((UserEntity entity, CancellationToken _) => userEntities.Add(entity)); - var userRepository = new TestDbSetRepository(mock.Object); - var service = new MyService(userRepository); - //act - await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); - // assert - var entity = mock.Object.Single(); - Assert.AreEqual(firstName, entity.FirstName); - Assert.AreEqual(lastName, entity.LastName); - Assert.AreEqual(dateOfBirth, entity.DateOfBirth); + //arrange + var userEntities = new List(); + var mock = userEntities.BuildMockDbSet(); + + mock.Setup(set => set.AddAsync(It.IsAny(), It.IsAny())) + .Callback((UserEntity entity, CancellationToken _) => userEntities.Add(entity)); + var userRepository = new TestDbSetRepository(mock.Object); + var service = new MyService(userRepository); + //act + await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); + // assert + var entity = mock.Object.Single(); + Assert.That(firstName, Is.EqualTo(entity.FirstName)); + Assert.That(lastName, Is.EqualTo(entity.LastName)); + Assert.That(dateOfBirth, Is.EqualTo(entity.DateOfBirth)); } - [TestCase("01/20/2012", "06/20/2018", 5)] + [TestCase("01/20/2012", "06/20/2018", 5)] [TestCase("01/20/2012", "06/20/2012", 4)] [TestCase("01/20/2012", "02/20/2012", 3)] [TestCase("01/20/2010", "02/20/2011", 0)] @@ -185,7 +185,7 @@ public async Task DbSetGetUserReports(DateTime from, DateTime to, int expectedCo //act var result = await service.GetUserReports(from, to); //assert - Assert.AreEqual(expectedCount, result.Count); + Assert.That(expectedCount, Is.EqualTo(result.Count)); } [TestCase("01/20/2012", "06/20/2018", 5)] @@ -194,18 +194,18 @@ public async Task DbSetGetUserReports(DateTime from, DateTime to, int expectedCo [TestCase("01/20/2010", "02/20/2011", 0)] public async Task DbSetCreatedFromCollectionGetUserReports(DateTime from, DateTime to, int expectedCount) { - //arrange - var users = CreateUserList(); - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock.Object); - var service = new MyService(userRepository); - //act - var result = await service.GetUserReports(from, to); - //assert - Assert.AreEqual(expectedCount, result.Count); + //arrange + var users = CreateUserList(); + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock.Object); + var service = new MyService(userRepository); + //act + var result = await service.GetUserReports(from, to); + //assert + Assert.That(expectedCount, Is.EqualTo(result.Count)); } - [TestCase] + [TestCase] public async Task DbSetGetAllUserEntity() { //arrange @@ -215,55 +215,50 @@ public async Task DbSetGetAllUserEntity() //act var result = await userRepository.GetAll(); //assert - Assert.AreEqual(users.Count, result.Count); + Assert.That(users.Count, Is.EqualTo(result.Count)); } [TestCase] public async Task DbSetCreatedFromCollectionGetAllUserEntity() { - //arrange - var users = CreateUserList(); - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock.Object); - //act - var result = await userRepository.GetAll(); - //assert - Assert.AreEqual(users.Count, result.Count); + //arrange + var users = CreateUserList(); + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock.Object); + //act + var result = await userRepository.GetAll(); + //assert + Assert.That(users.Count, Is.EqualTo(result.Count)); } - [TestCase] + [TestCase] public async Task DbSetFindAsyncUserEntity() { //arrange var userId = Guid.NewGuid(); var users = new List { - new UserEntity - { + new() { Id = Guid.NewGuid(), FirstName = "FirstName1", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, - new UserEntity - { + new() { Id = Guid.NewGuid(), FirstName = "FirstName2", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, - new UserEntity - { + new() { Id = userId, FirstName = "FirstName3", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, - new UserEntity - { + new() { Id = Guid.NewGuid(), FirstName = "FirstName3", LastName = "LastName", DateOfBirth = DateTime.Parse("03/20/2012", UsCultureInfo.DateTimeFormat) }, - new UserEntity - { + new() { Id = Guid.NewGuid(), FirstName = "FirstName5", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2018", UsCultureInfo.DateTimeFormat) @@ -273,7 +268,7 @@ public async Task DbSetFindAsyncUserEntity() var mock = users.AsQueryable().BuildMockDbSet(); mock.Setup(x => x.FindAsync(It.IsAny())).ReturnsAsync((object[] ids) => { - var id = (Guid) ids.First(); + var id = (Guid)ids.First(); return users.FirstOrDefault(x => x.Id == id); }); var userRepository = new TestDbSetRepository(mock.Object); @@ -282,67 +277,62 @@ public async Task DbSetFindAsyncUserEntity() var result = await ((DbSet)userRepository.GetQueryable()).FindAsync(userId); //assert - Assert.IsNotNull(result); - Assert.AreEqual("FirstName3", result.FirstName); + Assert.That(result, Is.Not.Null); + Assert.That("FirstName3", Is.EqualTo(result.FirstName)); } [TestCase] public async Task DbSetCreatedFromCollectionFindAsyncUserEntity() { - //arrange - var userId = Guid.NewGuid(); - var users = new List + //arrange + var userId = Guid.NewGuid(); + var users = new List { - new UserEntity - { + new() { Id = Guid.NewGuid(), FirstName = "FirstName1", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, - new UserEntity - { + new() { Id = Guid.NewGuid(), FirstName = "FirstName2", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, - new UserEntity - { + new() { Id = userId, FirstName = "FirstName3", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, - new UserEntity - { + new() { Id = Guid.NewGuid(), FirstName = "FirstName3", LastName = "LastName", DateOfBirth = DateTime.Parse("03/20/2012", UsCultureInfo.DateTimeFormat) }, - new UserEntity - { + new() { Id = Guid.NewGuid(), FirstName = "FirstName5", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2018", UsCultureInfo.DateTimeFormat) } }; - var mock = users.BuildMockDbSet(); - mock.Setup(x => x.FindAsync(It.IsAny())).ReturnsAsync((object[] ids) => - { - var id = (Guid)ids.First(); - return users.FirstOrDefault(x => x.Id == id); - }); - var userRepository = new TestDbSetRepository(mock.Object); + var mock = users.BuildMockDbSet(); + mock.Setup(x => x.FindAsync(It.IsAny())).ReturnsAsync((object[] ids) => + { + var id = (Guid)ids.First(); + return users.FirstOrDefault(x => x.Id == id); + }); + var userRepository = new TestDbSetRepository(mock.Object); - //act - var result = await ((DbSet)userRepository.GetQueryable()).FindAsync(userId); + //act + var result = await ((DbSet)userRepository.GetQueryable()).FindAsync(userId); - //assert - Assert.IsNotNull(result); - Assert.AreEqual("FirstName3", result.FirstName); + //assert + Assert.That(result, Is.Not.Null); + Assert.That("FirstName3", Is.EqualTo(result.FirstName)); } - [TestCase] + [TestCase] public async Task DbSetGetAllUserEntitiesAsync() { // arrange @@ -355,10 +345,10 @@ public async Task DbSetGetAllUserEntitiesAsync() var result = await userRepository.GetAllAsync().ToListAsync(); // assert - Assert.AreEqual(users.Count, result.Count); + Assert.That(users.Count, Is.EqualTo(result.Count)); } - - + + [TestCase] public async Task DbSetToListAsyncAsync_ShouldReturnAllEntities_WhenSourceIsChanged() { @@ -373,8 +363,8 @@ public async Task DbSetToListAsyncAsync_ShouldReturnAllEntities_WhenSourceIsChan var result2 = await mockDbSet.Object.ToListAsync(); // assert - Assert.AreEqual(0, result1.Count); - Assert.AreEqual(users.Count, result2.Count); + Assert.That(0, Is.EqualTo(result1.Count)); + Assert.That(users.Count, Is.EqualTo(result2.Count)); } @@ -382,20 +372,20 @@ public async Task DbSetToListAsyncAsync_ShouldReturnAllEntities_WhenSourceIsChan [TestCase] public async Task DbSetCreatedFromCollectionGetAllUserEntitiesAsync() { - // arrange - var users = CreateUserList(); + // arrange + var users = CreateUserList(); - var mockDbSet = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet.Object); + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet.Object); - // act - var result = await userRepository.GetAllAsync().ToListAsync(); + // act + var result = await userRepository.GetAllAsync().ToListAsync(); - // assert - Assert.AreEqual(users.Count, result.Count); + // assert + Assert.That(users.Count, Is.EqualTo(result.Count)); } - private static List CreateUserList() => new List + private static List CreateUserList() => new() { new UserEntity { FirstName = "FirstName1", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, new UserEntity { FirstName = "FirstName2", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, diff --git a/src/MockQueryable/MockQueryable.Sample/MyServiceNSubstituteTests.cs b/src/MockQueryable/MockQueryable.Sample/MyServiceNSubstituteTests.cs index 1f9e08c..4a1ccb9 100644 --- a/src/MockQueryable/MockQueryable.Sample/MyServiceNSubstituteTests.cs +++ b/src/MockQueryable/MockQueryable.Sample/MyServiceNSubstituteTests.cs @@ -9,336 +9,329 @@ namespace MockQueryable.Sample { - [TestFixture] - public class MyServiceNSubstituteTests + [TestFixture] + public class MyServiceNSubstituteTests + { + private static readonly CultureInfo UsCultureInfo = new("en-US"); + + [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] + [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] + [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] + public void CreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) { - private static readonly CultureInfo UsCultureInfo = new CultureInfo("en-US"); - - - [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] - [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] - [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] - public void CreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) - { - //arrange - var userRepository = Substitute.For(); - var service = new MyService(userRepository); - var users = new List - { - new UserEntity{LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, - new UserEntity{FirstName = "ExistFirstName"}, - new UserEntity{DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, - new UserEntity{DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, - new UserEntity{DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, - }; - //expect - var mock = users.BuildMock(); - userRepository.GetQueryable().Returns(mock); - //act - var ex= Assert.ThrowsAsync(() => service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); - //assert - Assert.AreEqual(expectedError, ex.Message); - - } - - [TestCase("01/20/2012", "06/20/2018",5)] - [TestCase("01/20/2012", "06/20/2012",4)] - [TestCase("01/20/2012", "02/20/2012",3)] - [TestCase("01/20/2010", "02/20/2011",0)] - public async Task GetUserReports(DateTime from, DateTime to, int expectedCount) - { - //arrange - var userRepository = Substitute.For(); - var service = new MyService(userRepository); - List users = CreateUserList(); - - //expect - var mock = users.BuildMock(); - userRepository.GetQueryable().Returns(mock); - //act - var result = await service.GetUserReports(from, to); - //assert - Assert.AreEqual(expectedCount, result.Count); - } - - [TestCase("01/20/2012", "06/20/2018", 5)] - [TestCase("01/20/2012", "06/20/2012", 4)] - [TestCase("01/20/2012", "02/20/2012", 3)] - [TestCase("01/20/2010", "02/20/2011", 0)] - public async Task GetUserReports_AutoMap(DateTime from, DateTime to, int expectedCount) - { - //arrange - List users = CreateUserList(); - - var mock = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - //act - var result = await service.GetUserReportsAutoMap(from, to); - //assert - Assert.AreEqual(expectedCount, result.Count); - - } - - [TestCase("01/20/2012", "06/20/2018", 5)] - [TestCase("01/20/2012", "06/20/2012", 4)] - [TestCase("01/20/2012", "02/20/2012", 3)] - [TestCase("01/20/2010", "02/20/2011", 0)] - public async Task GetUserReports_AutoMap_FromDbSetCreatedFromCollection(DateTime from, DateTime to, int expectedCount) - { - //arrange - List users = CreateUserList(); - - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - //act - var result = await service.GetUserReportsAutoMap(from, to); - //assert - Assert.AreEqual(expectedCount, result.Count); - - } - - [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] - [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] - [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] - public void DbSetCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) - { - //arrange - var users = new List - { - new UserEntity{LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, - new UserEntity{FirstName = "ExistFirstName"}, - new UserEntity{DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, - new UserEntity{DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, - new UserEntity{DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, - }; - var mock = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - //act - var ex = Assert.ThrowsAsync(() => service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); - //assert - Assert.AreEqual(expectedError, ex.Message); + //arrange + var userRepository = Substitute.For(); + var service = new MyService(userRepository); + var users = new List + { + new() {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, + new() {FirstName = "ExistFirstName"}, + new() {DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, + new() {DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, + new() {DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, + }; + //expect + var mock = users.BuildMock(); + userRepository.GetQueryable().Returns(mock); + //act + var ex = Assert.ThrowsAsync(() => service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); + //assert + Assert.That(expectedError, Is.EqualTo(ex.Message)); - } + } + [TestCase("01/20/2012", "06/20/2018", 5)] + [TestCase("01/20/2012", "06/20/2012", 4)] + [TestCase("01/20/2012", "02/20/2012", 3)] + [TestCase("01/20/2010", "02/20/2011", 0)] + public async Task GetUserReports(DateTime from, DateTime to, int expectedCount) + { + //arrange + var userRepository = Substitute.For(); + var service = new MyService(userRepository); + List users = CreateUserList(); + + //expect + var mock = users.BuildMock(); + userRepository.GetQueryable().Returns(mock); + //act + var result = await service.GetUserReports(from, to); + //assert + Assert.That(expectedCount, Is.EqualTo(result.Count)); + } - [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] - [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] - [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] - public void DbSetCreatedFromCollectionCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) - { - //arrange - var users = new List + [TestCase("01/20/2012", "06/20/2018", 5)] + [TestCase("01/20/2012", "06/20/2012", 4)] + [TestCase("01/20/2012", "02/20/2012", 3)] + [TestCase("01/20/2010", "02/20/2011", 0)] + public async Task GetUserReports_AutoMap(DateTime from, DateTime to, int expectedCount) + { + //arrange + List users = CreateUserList(); + + var mock = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + //act + var result = await service.GetUserReportsAutoMap(from, to); + //assert + Assert.That(expectedCount, Is.EqualTo(result.Count)); + } + + [TestCase("01/20/2012", "06/20/2018", 5)] + [TestCase("01/20/2012", "06/20/2012", 4)] + [TestCase("01/20/2012", "02/20/2012", 3)] + [TestCase("01/20/2010", "02/20/2011", 0)] + public async Task GetUserReports_AutoMap_FromDbSetCreatedFromCollection(DateTime from, DateTime to, int expectedCount) + { + //arrange + List users = CreateUserList(); + + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + //act + var result = await service.GetUserReportsAutoMap(from, to); + //assert + Assert.That(expectedCount, Is.EqualTo(result.Count)); + } + + [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] + [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] + [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] + public void DbSetCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) + { + //arrange + var users = new List { - new UserEntity{LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, - new UserEntity{FirstName = "ExistFirstName"}, - new UserEntity{DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, - new UserEntity{DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, - new UserEntity{DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, + new() {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, + new() {FirstName = "ExistFirstName"}, + new() {DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, + new() {DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, + new() {DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, }; - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - //act - var ex = Assert.ThrowsAsync(() => service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); - //assert - Assert.AreEqual(expectedError, ex.Message); - - } - - [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] - public async Task DbSetCreateUser(string firstName, string lastName, DateTime dateOfBirth) - { - //arrange - var userEntities = new List(); - var mock = userEntities.AsQueryable().BuildMockDbSet(); - mock.AddAsync(Arg.Any()) - .Returns(info => null) - .AndDoes(info => userEntities.Add(info.Arg())); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - //act - await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); - // assert - var entity = mock.Single(); - Assert.AreEqual(firstName, entity.FirstName); - Assert.AreEqual(lastName, entity.LastName); - Assert.AreEqual(dateOfBirth, entity.DateOfBirth); - } - - [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] - public async Task DbSetCreatedFromCollectionCreateUser(string firstName, string lastName, DateTime dateOfBirth) - { - //arrange - var userEntities = new List(); - var mock = userEntities.BuildMockDbSet(); - mock.AddAsync(Arg.Any()) - .Returns(info => null) - .AndDoes(info => userEntities.Add(info.Arg())); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - //act - await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); - // assert - var entity = mock.Single(); - Assert.AreEqual(firstName, entity.FirstName); - Assert.AreEqual(lastName, entity.LastName); - Assert.AreEqual(dateOfBirth, entity.DateOfBirth); - } - - [TestCase("01/20/2012", "06/20/2018", 5)] - [TestCase("01/20/2012", "06/20/2012", 4)] - [TestCase("01/20/2012", "02/20/2012", 3)] - [TestCase("01/20/2010", "02/20/2011", 0)] - public async Task DbSetGetUserReports(DateTime from, DateTime to, int expectedCount) - { - //arrange - var users = CreateUserList(); - - var mock = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - //act - var result = await service.GetUserReports(from, to); - //assert - Assert.AreEqual(expectedCount, result.Count); - } - - [TestCase("01/20/2012", "06/20/2018", 5)] - [TestCase("01/20/2012", "06/20/2012", 4)] - [TestCase("01/20/2012", "02/20/2012", 3)] - [TestCase("01/20/2010", "02/20/2011", 0)] - public async Task DbSetCreatedFromCollectionGetUserReports(DateTime from, DateTime to, int expectedCount) - { - //arrange - var users = CreateUserList(); - - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - //act - var result = await service.GetUserReports(from, to); - //assert - Assert.AreEqual(expectedCount, result.Count); - } - - [TestCase] - public async Task DbSetGetAllUserEntity() - { - //arrange - var users = CreateUserList(); - var mock = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - //act - var result = await userRepository.GetAll(); - //assert - Assert.AreEqual(users.Count, result.Count); - } - - [TestCase] - public async Task DbSetCreatedFromCollectionGetAllUserEntity() - { - //arrange - var users = CreateUserList(); - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - //act - var result = await userRepository.GetAll(); - //assert - Assert.AreEqual(users.Count, result.Count); - } - - [TestCase] - public async Task DbSetGetAllUserEntitiesAsync() - { - // arrange - var users = CreateUserList(); - - var mockDbSet = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet); - - // act - var result = await userRepository.GetAllAsync().ToListAsync(); - - // assert - Assert.AreEqual(users.Count, result.Count); - } - - - [TestCase] - public async Task DbSetGetAllUserEntitiesAsync_ShouldReturnAllEntities_WhenSourceIsChanged() - { - // arrange - var users = new List(); + var mock = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + //act + var ex = Assert.ThrowsAsync(() => service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); + //assert + Assert.That(expectedError, Is.EqualTo(ex.Message)); + } - var mockDbSet = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet); + [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] + [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] + [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] + public void DbSetCreatedFromCollectionCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) + { + //arrange + var users = new List + { + new() {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, + new() {FirstName = "ExistFirstName"}, + new() {DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, + new() {DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, + new() {DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, + }; + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + //act + var ex = Assert.ThrowsAsync(() => service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); + //assert + Assert.That(expectedError, Is.EqualTo(ex.Message)); + } - // act - var result1 = await userRepository.GetAllAsync().ToListAsync(); - users.AddRange(CreateUserList()); - var result2 = await userRepository.GetAllAsync().ToListAsync(); + [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] + public async Task DbSetCreateUser(string firstName, string lastName, DateTime dateOfBirth) + { + //arrange + var userEntities = new List(); + var mock = userEntities.AsQueryable().BuildMockDbSet(); + mock.AddAsync(Arg.Any()) + .Returns(info => null) + .AndDoes(info => userEntities.Add(info.Arg())); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + //act + await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); + // assert + var entity = mock.Single(); + Assert.That(firstName, Is.EqualTo(entity.FirstName)); + Assert.That(lastName, Is.EqualTo(entity.LastName)); + Assert.That(dateOfBirth, Is.EqualTo(entity.DateOfBirth)); + } - // assert - Assert.AreEqual(0, result1.Count); - Assert.AreEqual(users.Count, result2.Count); - } + [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] + public async Task DbSetCreatedFromCollectionCreateUser(string firstName, string lastName, DateTime dateOfBirth) + { + //arrange + var userEntities = new List(); + var mock = userEntities.BuildMockDbSet(); + mock.AddAsync(Arg.Any()) + .Returns(info => null) + .AndDoes(info => userEntities.Add(info.Arg())); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + //act + await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); + // assert + var entity = mock.Single(); + Assert.That(firstName, Is.EqualTo(entity.FirstName)); + Assert.That(lastName, Is.EqualTo(entity.LastName)); + Assert.That(dateOfBirth, Is.EqualTo(entity.DateOfBirth)); + } - [TestCase] - public async Task DbSetCreatedFromCollectionGetAllUserEntitiesAsync() - { - // arrange - var users = CreateUserList(); + [TestCase("01/20/2012", "06/20/2018", 5)] + [TestCase("01/20/2012", "06/20/2012", 4)] + [TestCase("01/20/2012", "02/20/2012", 3)] + [TestCase("01/20/2010", "02/20/2011", 0)] + public async Task DbSetGetUserReports(DateTime from, DateTime to, int expectedCount) + { + //arrange + var users = CreateUserList(); + + var mock = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + //act + var result = await service.GetUserReports(from, to); + //assert + Assert.That(expectedCount, Is.EqualTo(result.Count)); + } - var mockDbSet = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet); + [TestCase("01/20/2012", "06/20/2018", 5)] + [TestCase("01/20/2012", "06/20/2012", 4)] + [TestCase("01/20/2012", "02/20/2012", 3)] + [TestCase("01/20/2010", "02/20/2011", 0)] + public async Task DbSetCreatedFromCollectionGetUserReports(DateTime from, DateTime to, int expectedCount) + { + //arrange + var users = CreateUserList(); + + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + //act + var result = await service.GetUserReports(from, to); + //assert + Assert.That(expectedCount, Is.EqualTo(result.Count)); + } - // act - var result = await userRepository.GetAllAsync().ToListAsync(); + [TestCase] + public async Task DbSetGetAllUserEntity() + { + //arrange + var users = CreateUserList(); + var mock = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + //act + var result = await userRepository.GetAll(); + //assert + Assert.That(users.Count, Is.EqualTo(result.Count)); + } - // assert - Assert.AreEqual(users.Count, result.Count); - } + [TestCase] + public async Task DbSetCreatedFromCollectionGetAllUserEntity() + { + //arrange + var users = CreateUserList(); + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + //act + var result = await userRepository.GetAll(); + //assert + Assert.That(users.Count, Is.EqualTo(result.Count)); + } - [TestCase] - public async Task DbSetGetOneUserTntityAsync() - { - // arrange - var users = CreateUserList(); + [TestCase] + public async Task DbSetGetAllUserEntitiesAsync() + { + // arrange + var users = CreateUserList(); - var mockDbSet = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet); + var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); - // act - var result = await userRepository.GetAllAsync() - .Where(user => user.FirstName == "FirstName1") - .FirstOrDefaultAsync(); + // act + var result = await userRepository.GetAllAsync().ToListAsync(); - // assert - Assert.AreEqual(users.First(), result); - } + // assert + Assert.That(users.Count, Is.EqualTo(result.Count)); + } - [TestCase] - public async Task DbSetCreatedFromCollectionGetOneUserTntityAsync() - { - // arrange - var users = CreateUserList(); + [TestCase] + public async Task DbSetGetAllUserEntitiesAsync_ShouldReturnAllEntities_WhenSourceIsChanged() + { + // arrange + var users = new List(); + + var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); + + // act + var result1 = await userRepository.GetAllAsync().ToListAsync(); + users.AddRange(CreateUserList()); + var result2 = await userRepository.GetAllAsync().ToListAsync(); + + // assert + Assert.That(0, Is.EqualTo(result1.Count)); + Assert.That(users.Count, Is.EqualTo(result2.Count)); + } - var mockDbSet = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet); + [TestCase] + public async Task DbSetCreatedFromCollectionGetAllUserEntitiesAsync() + { + // arrange + var users = CreateUserList(); + + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); - // act - var result = await userRepository.GetAllAsync() - .Where(user => user.FirstName == "FirstName1") - .FirstOrDefaultAsync(); + // act + var result = await userRepository.GetAllAsync().ToListAsync(); - // assert - Assert.AreEqual(users.First(), result); - } + // assert + Assert.That(users.Count, Is.EqualTo(result.Count)); + } + + [TestCase] + public async Task DbSetGetOneUserTntityAsync() + { + // arrange + var users = CreateUserList(); + + var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); + + // act + var result = await userRepository.GetAllAsync() + .Where(user => user.FirstName == "FirstName1") + .FirstOrDefaultAsync(); + + // assert + Assert.That(users.First(), Is.EqualTo(result)); + } - private static List CreateUserList() => new List + [TestCase] + public async Task DbSetCreatedFromCollectionGetOneUserTntityAsync() + { + // arrange + var users = CreateUserList(); + + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); + + // act + var result = await userRepository.GetAllAsync() + .Where(user => user.FirstName == "FirstName1") + .FirstOrDefaultAsync(); + + // assert + Assert.That(users.First(), Is.EqualTo(result)); + } + + private static List CreateUserList() => new() { new UserEntity { FirstName = "FirstName1", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, new UserEntity { FirstName = "FirstName2", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, @@ -346,6 +339,5 @@ public async Task DbSetCreatedFromCollectionGetOneUserTntityAsync() new UserEntity { FirstName = "FirstName3", LastName = "LastName", DateOfBirth = DateTime.Parse("03/20/2012", UsCultureInfo.DateTimeFormat) }, new UserEntity { FirstName = "FirstName5", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2018", UsCultureInfo.DateTimeFormat) }, }; - - } + } } From 4af9128c34db7946200259b0c39c00dd43698912 Mon Sep 17 00:00:00 2001 From: Catlandor Date: Fri, 18 Jul 2025 17:49:09 +0200 Subject: [PATCH 5/8] #73: New feature: Support for custom ExpressionVisitor --- .../MockQueryable.Core/TestQueryProvider.cs | 9 +- .../MockQueryableExtensions.cs | 22 ++- .../TestQueryProviderEfCore.cs | 7 +- .../FakeItEasyExtensions.cs | 133 +++++++++++------- .../MockQueryable.Moq/MoqExtensions.cs | 69 ++++++--- .../NSubstituteExtensions.cs | 40 +++++- .../MockQueryable.Sample.csproj | 1 + .../MockQueryable.Sample/MyService.cs | 2 +- .../MyServiceFakeItEasyTests.cs | 39 ++++- .../MockQueryable.Sample/MyServiceMoqTests.cs | 44 +++++- .../MyServiceNSubstituteTests.cs | 38 ++++- .../SampleILikeExpressionVisitor .cs | 40 ++++++ .../TestDbSetRepository.cs | 51 ++++--- 13 files changed, 384 insertions(+), 111 deletions(-) create mode 100644 src/MockQueryable/MockQueryable.Sample/SampleILikeExpressionVisitor .cs diff --git a/src/MockQueryable/MockQueryable.Core/TestQueryProvider.cs b/src/MockQueryable/MockQueryable.Core/TestQueryProvider.cs index 264b051..92a5a95 100644 --- a/src/MockQueryable/MockQueryable.Core/TestQueryProvider.cs +++ b/src/MockQueryable/MockQueryable.Core/TestQueryProvider.cs @@ -6,8 +6,9 @@ namespace MockQueryable.Core { - public abstract class TestQueryProvider : IOrderedQueryable, IQueryProvider - { + public abstract class TestQueryProvider : IOrderedQueryable, IQueryProvider + where TExpressionVisitor : ExpressionVisitor, new() + { private IEnumerable _enumerable; protected TestQueryProvider(Expression expression) @@ -40,7 +41,7 @@ public IQueryable CreateQuery(Expression expression) private object CreateInstance(Type tElement, Expression expression) { - var queryType = GetType().GetGenericTypeDefinition().MakeGenericType(tElement); + var queryType = GetType().GetGenericTypeDefinition().MakeGenericType(tElement, typeof(TExpressionVisitor)); return Activator.CreateInstance(queryType, expression); } @@ -74,7 +75,7 @@ IEnumerator IEnumerable.GetEnumerator() private static TResult CompileExpressionItem(Expression expression) { - var visitor = new TestExpressionVisitor(); + var visitor = new TExpressionVisitor(); var body = visitor.Visit(expression); var f = Expression.Lambda>(body ?? throw new InvalidOperationException($"{nameof(body)} is null"), (IEnumerable) null); return f.Compile()(); diff --git a/src/MockQueryable/MockQueryable.EntityFrameworkCore/MockQueryableExtensions.cs b/src/MockQueryable/MockQueryable.EntityFrameworkCore/MockQueryableExtensions.cs index c94b1c8..93157df 100644 --- a/src/MockQueryable/MockQueryable.EntityFrameworkCore/MockQueryableExtensions.cs +++ b/src/MockQueryable/MockQueryable.EntityFrameworkCore/MockQueryableExtensions.cs @@ -1,6 +1,8 @@ -using MockQueryable.EntityFrameworkCore; +using MockQueryable.Core; +using MockQueryable.EntityFrameworkCore; using System.Collections.Generic; using System.Linq; +using System.Linq.Expressions; // Moving MockQueryableExtensions BuildMock into the MockQueryable.EntityFrameworkCore // namespace had breaking changes with earlier extensions added to MockQueryable.Moq @@ -9,11 +11,19 @@ // is dependent on the EF Core AsyncEnumerable. namespace MockQueryable { - public static class MockQueryableExtensions + public static class MockQueryableExtensions + { + public static IQueryable BuildMock(this IEnumerable data) + where TEntity : class { - public static IQueryable BuildMock(this IEnumerable data) where TEntity : class - { - return new TestAsyncEnumerableEfCore(data); - } + return new TestAsyncEnumerableEfCore(data); } + + public static IQueryable BuildMock(this IEnumerable data) + where TEntity : class + where TExpressionVisitor : ExpressionVisitor, new() + { + return new TestAsyncEnumerableEfCore(data); + } + } } diff --git a/src/MockQueryable/MockQueryable.EntityFrameworkCore/TestQueryProviderEfCore.cs b/src/MockQueryable/MockQueryable.EntityFrameworkCore/TestQueryProviderEfCore.cs index 9b637ba..038b856 100644 --- a/src/MockQueryable/MockQueryable.EntityFrameworkCore/TestQueryProviderEfCore.cs +++ b/src/MockQueryable/MockQueryable.EntityFrameworkCore/TestQueryProviderEfCore.cs @@ -8,7 +8,8 @@ namespace MockQueryable.EntityFrameworkCore { - public class TestAsyncEnumerableEfCore: TestQueryProvider, IAsyncEnumerable, IAsyncQueryProvider + public class TestAsyncEnumerableEfCore: TestQueryProvider, IAsyncEnumerable, IAsyncQueryProvider + where TExpressionVisitor : ExpressionVisitor, new() { public TestAsyncEnumerableEfCore(Expression expression) : base(expression) { @@ -25,11 +26,11 @@ public TResult ExecuteAsync(Expression expression, CancellationToken ca .GetMethods() .First(method => method.Name == nameof(IQueryProvider.Execute) && method.IsGenericMethod) .MakeGenericMethod(expectedResultType) - .Invoke(this, new object[] { expression }); + .Invoke(this, [expression]); return (TResult)typeof(Task).GetMethod(nameof(Task.FromResult)) .MakeGenericMethod(expectedResultType) - .Invoke(null, new[] { executionResult }); + .Invoke(null, [executionResult]); } public IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) diff --git a/src/MockQueryable/MockQueryable.FakeItEasy/FakeItEasyExtensions.cs b/src/MockQueryable/MockQueryable.FakeItEasy/FakeItEasyExtensions.cs index ee8c1b0..2fd7c40 100644 --- a/src/MockQueryable/MockQueryable.FakeItEasy/FakeItEasyExtensions.cs +++ b/src/MockQueryable/MockQueryable.FakeItEasy/FakeItEasyExtensions.cs @@ -1,68 +1,105 @@ using FakeItEasy; using Microsoft.EntityFrameworkCore; +using MockQueryable.Core; using MockQueryable.EntityFrameworkCore; using System.Collections.Generic; using System.Linq; +using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; namespace MockQueryable.FakeItEasy { - public static class FakeItEasyExtensions + public static class FakeItEasyExtensions + { + public static DbSet BuildMockDbSet(this IEnumerable data) + where TEntity : class + where TExpressionVisitor : ExpressionVisitor, new() + => data.BuildMock().BuildMockDbSet(); + + public static DbSet BuildMockDbSet(this IEnumerable data) + where TEntity : class + => data.BuildMock().BuildMockDbSet(); + + /// + /// This method allows you to create a mock DbSet for testing purposes. + /// It is particularly useful when you want to simulate the behavior of Entity Framework Core's DbSet + /// with custom expression handling, such as for testing LINQ queries or database operations. + /// The method takes an IQueryable of the entity type and returns a mocked DbSet that implements + /// both IAsyncEnumerable and IQueryable interfaces, allowing for asynchronous enumeration + /// and LINQ query capabilities. + /// + /// + /// The type of the entity that the DbSet will represent. + /// + public static DbSet BuildMockDbSet(this IQueryable data) where TEntity : class { - public static DbSet BuildMockDbSet(this IEnumerable data) where TEntity : class => data.BuildMock().BuildMockDbSet(); + return BuildMockDbSet(data); + } - public static DbSet BuildMockDbSet(this IQueryable data) where TEntity : class - { - var mock = A.Fake>(d => d.Implements>().Implements>()); - var enumerable = new TestAsyncEnumerableEfCore(data); - mock.ConfigureQueryableCalls(enumerable, data); - mock.ConfigureAsyncEnumerableCalls(enumerable); - mock.ConfigureDbSetCalls(data); - if (mock is IAsyncEnumerable asyncEnumerable) - { - A.CallTo(() => asyncEnumerable.GetAsyncEnumerator(A.Ignored)).ReturnsLazily(() => enumerable.GetAsyncEnumerator()); - } - return mock; - } + /// + /// See . + /// + /// + /// The type of the entity that the DbSet will represent. + /// + /// + /// The type of the expression visitor that will be used to process LINQ expressions. + /// Can be used to mock EF Core specific expression handling, such as for ILike expressions. + /// + public static DbSet BuildMockDbSet(this IQueryable data) + where TEntity : class + where TExpressionVisitor : ExpressionVisitor, new() + { + var mock = A.Fake>(d => d.Implements>().Implements>()); + var enumerable = new TestAsyncEnumerableEfCore(data); + mock.ConfigureQueryableCalls(enumerable, data); + mock.ConfigureAsyncEnumerableCalls(enumerable); + mock.ConfigureDbSetCalls(data); + if (mock is IAsyncEnumerable asyncEnumerable) + { + A.CallTo(() => asyncEnumerable.GetAsyncEnumerator(A.Ignored)).ReturnsLazily(() => enumerable.GetAsyncEnumerator()); + } - private static void ConfigureQueryableCalls( - this IQueryable mock, - IQueryProvider queryProvider, - IQueryable data) where TEntity : class - { - A.CallTo(() => mock.Provider).Returns(queryProvider); - A.CallTo(() => mock.Expression).Returns(data?.Expression); - A.CallTo(() => mock.ElementType).Returns(data?.ElementType); - A.CallTo(() => mock.GetEnumerator()).ReturnsLazily(() => data?.GetEnumerator()); - } + return mock; + } - private static void ConfigureAsyncEnumerableCalls( - this DbSet mock, - IAsyncEnumerable enumerable) where TEntity : class - { - A.CallTo(() => mock.GetAsyncEnumerator(A.Ignored)) - .Returns(enumerable.GetAsyncEnumerator()); - - } + private static void ConfigureQueryableCalls( + this IQueryable mock, + IQueryProvider queryProvider, + IQueryable data) where TEntity : class + { + A.CallTo(() => mock.Provider).Returns(queryProvider); + A.CallTo(() => mock.Expression).Returns(data?.Expression); + A.CallTo(() => mock.ElementType).Returns(data?.ElementType); + A.CallTo(() => mock.GetEnumerator()).ReturnsLazily(() => data?.GetEnumerator()); + } - private static void ConfigureDbSetCalls(this DbSet mock, IQueryable data) - where TEntity : class - { - A.CallTo(() => mock.AsQueryable()).Returns(data); - A.CallTo(() => mock.AsAsyncEnumerable()).ReturnsLazily(args => CreateAsyncMock(data)); - } + private static void ConfigureAsyncEnumerableCalls( + this DbSet mock, + IAsyncEnumerable enumerable) where TEntity : class + { + A.CallTo(() => mock.GetAsyncEnumerator(A.Ignored)) + .Returns(enumerable.GetAsyncEnumerator()); + } + + private static void ConfigureDbSetCalls(this DbSet mock, IQueryable data) + where TEntity : class + { + A.CallTo(() => mock.AsQueryable()).Returns(data); + A.CallTo(() => mock.AsAsyncEnumerable()).ReturnsLazily(args => CreateAsyncMock(data)); + } - private static async IAsyncEnumerable CreateAsyncMock(IEnumerable data) - where TEntity : class - { - foreach (var entity in data) - { - yield return entity; - } + private static async IAsyncEnumerable CreateAsyncMock(IEnumerable data) + where TEntity : class + { + foreach (var entity in data) + { + yield return entity; + } - await Task.CompletedTask; - } + await Task.CompletedTask; } + } } \ No newline at end of file diff --git a/src/MockQueryable/MockQueryable.Moq/MoqExtensions.cs b/src/MockQueryable/MockQueryable.Moq/MoqExtensions.cs index dafd6b0..c169f3b 100644 --- a/src/MockQueryable/MockQueryable.Moq/MoqExtensions.cs +++ b/src/MockQueryable/MockQueryable.Moq/MoqExtensions.cs @@ -1,32 +1,69 @@ -using System.Collections.Generic; +using Microsoft.EntityFrameworkCore; +using MockQueryable.Core; +using MockQueryable.EntityFrameworkCore; +using Moq; +using System.Collections.Generic; using System.Linq; +using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using MockQueryable.EntityFrameworkCore; -using Moq; namespace MockQueryable.Moq { public static class MoqExtensions { - public static Mock> BuildMockDbSet(this IEnumerable data) where TEntity : class => data.BuildMock().BuildMockDbSet(); + public static Mock> BuildMockDbSet(this IEnumerable data) + where TEntity : class + where TExpressionVisitor : ExpressionVisitor, new() + => data.BuildMock().BuildMockDbSet(); - public static Mock> BuildMockDbSet(this IQueryable data) where TEntity : class + public static Mock> BuildMockDbSet(this IEnumerable data) + where TEntity : class + => data.BuildMock().BuildMockDbSet(); + + /// + /// This method allows you to create a mock DbSet for testing purposes. + /// It is particularly useful when you want to simulate the behavior of Entity Framework Core's DbSet + /// with custom expression handling, such as for testing LINQ queries or database operations. + /// The method takes an IQueryable of the entity type and returns a mocked DbSet that implements + /// both IAsyncEnumerable and IQueryable interfaces, allowing for asynchronous enumeration + /// and LINQ query capabilities. + /// + /// + /// The type of the entity that the DbSet will represent. + /// + public static Mock> BuildMockDbSet(this IQueryable data) where TEntity : class { - var mock = new Mock>(); - var enumerable = new TestAsyncEnumerableEfCore(data); - mock.ConfigureAsyncEnumerableCalls(enumerable); - mock.As>().ConfigureQueryableCalls(enumerable, data); - mock.As>().Setup(x => x.GetAsyncEnumerator(It.IsAny())).Returns(() => enumerable.GetAsyncEnumerator()); - mock.Setup(m => m.AsQueryable()).Returns(enumerable); + return BuildMockDbSet(data); + } - mock.ConfigureDbSetCalls(data); - return mock; - } + /// + /// See . + /// + /// + /// The type of the entity that the DbSet will represent. + /// + /// + /// The type of the expression visitor that will be used to process LINQ expressions. + /// Can be used to mock EF Core specific expression handling, such as for ILike expressions. + /// + public static Mock> BuildMockDbSet(this IQueryable data) + where TEntity : class + where TExpressionVisitor : ExpressionVisitor, new() + { + var mock = new Mock>(); + var enumerable = new TestAsyncEnumerableEfCore(data); + mock.ConfigureAsyncEnumerableCalls(enumerable); + mock.As>().ConfigureQueryableCalls(enumerable, data); + mock.As>().Setup(x => x.GetAsyncEnumerator(It.IsAny())).Returns(() => enumerable.GetAsyncEnumerator()); + mock.Setup(m => m.AsQueryable()).Returns(enumerable); + + mock.ConfigureDbSetCalls(data); + return mock; + } - private static void ConfigureDbSetCalls(this Mock> mock, IQueryable data) + private static void ConfigureDbSetCalls(this Mock> mock, IQueryable data) where TEntity : class { mock.Setup(m => m.AsQueryable()).Returns(mock.Object); diff --git a/src/MockQueryable/MockQueryable.NSubstitute/NSubstituteExtensions.cs b/src/MockQueryable/MockQueryable.NSubstitute/NSubstituteExtensions.cs index 0db0998..1a2e25e 100644 --- a/src/MockQueryable/MockQueryable.NSubstitute/NSubstituteExtensions.cs +++ b/src/MockQueryable/MockQueryable.NSubstitute/NSubstituteExtensions.cs @@ -1,8 +1,10 @@ using Microsoft.EntityFrameworkCore; +using MockQueryable.Core; using MockQueryable.EntityFrameworkCore; using NSubstitute; using System.Collections.Generic; using System.Linq; +using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; @@ -10,12 +12,45 @@ namespace MockQueryable.NSubstitute { public static class NSubstituteExtensions { + public static DbSet BuildMockDbSet(this IEnumerable data) + where TEntity : class + where TExpressionVisitor : ExpressionVisitor, new() + => data.BuildMock().BuildMockDbSet(); + public static DbSet BuildMockDbSet(this IEnumerable data) where TEntity : class => data.BuildMock().BuildMockDbSet(); + /// + /// This method allows you to create a mock DbSet for testing purposes. + /// It is particularly useful when you want to simulate the behavior of Entity Framework Core's DbSet + /// with custom expression handling, such as for testing LINQ queries or database operations. + /// The method takes an IQueryable of the entity type and returns a mocked DbSet that implements + /// both IAsyncEnumerable and IQueryable interfaces, allowing for asynchronous enumeration + /// and LINQ query capabilities. + /// + /// + /// The type of the entity that the DbSet will represent. + /// public static DbSet BuildMockDbSet(this IQueryable data) where TEntity : class + { + return BuildMockDbSet(data); + } + + /// + /// See . + /// + /// + /// The type of the entity that the DbSet will represent. + /// + /// + /// The type of the expression visitor that will be used to process LINQ expressions. + /// Can be used to mock EF Core specific expression handling, such as for ILike expressions. + /// + public static DbSet BuildMockDbSet(this IQueryable data) + where TEntity : class + where TExpressionVisitor : ExpressionVisitor, new() { var mock = Substitute.For, IQueryable, IAsyncEnumerable>(); - var enumerable = new TestAsyncEnumerableEfCore(data); + var enumerable = new TestAsyncEnumerableEfCore(data); mock.ConfigureAsyncEnumerableCalls(enumerable); mock.ConfigureQueryableCalls(enumerable, data); @@ -23,13 +58,12 @@ public static DbSet BuildMockDbSet(this IQueryable da if (mock is IAsyncEnumerable asyncEnumerable) { - asyncEnumerable.GetAsyncEnumerator(Arg.Any()).Returns(args => enumerable.GetAsyncEnumerator()); + asyncEnumerable.GetAsyncEnumerator(Arg.Any()).Returns(args => enumerable.GetAsyncEnumerator()); } return mock; } - private static void ConfigureQueryableCalls( this IQueryable mock, IQueryProvider queryProvider, diff --git a/src/MockQueryable/MockQueryable.Sample/MockQueryable.Sample.csproj b/src/MockQueryable/MockQueryable.Sample/MockQueryable.Sample.csproj index e2d3c68..60dbdf8 100644 --- a/src/MockQueryable/MockQueryable.Sample/MockQueryable.Sample.csproj +++ b/src/MockQueryable/MockQueryable.Sample/MockQueryable.Sample.csproj @@ -7,6 +7,7 @@ + all diff --git a/src/MockQueryable/MockQueryable.Sample/MyService.cs b/src/MockQueryable/MockQueryable.Sample/MyService.cs index eb402d5..402e08f 100644 --- a/src/MockQueryable/MockQueryable.Sample/MyService.cs +++ b/src/MockQueryable/MockQueryable.Sample/MyService.cs @@ -12,7 +12,7 @@ namespace MockQueryable.Sample public class MyService { private readonly IUserRepository _userRepository; - private static readonly MapperConfiguration _mapperConfiguration = new MapperConfiguration( + private static readonly MapperConfiguration _mapperConfiguration = new( cfg => { cfg.CreateMap() diff --git a/src/MockQueryable/MockQueryable.Sample/MyServiceFakeItEasyTests.cs b/src/MockQueryable/MockQueryable.Sample/MyServiceFakeItEasyTests.cs index 4090dad..039b6ad 100644 --- a/src/MockQueryable/MockQueryable.Sample/MyServiceFakeItEasyTests.cs +++ b/src/MockQueryable/MockQueryable.Sample/MyServiceFakeItEasyTests.cs @@ -130,7 +130,7 @@ public void DbSetCreatedFromCollectionCreateUserIfNotExist(string firstName, str var service = new MyService(userRepository); // act var ex = Assert.ThrowsAsync(() => - service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); + service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); // assert Assert.That(expectedError, Is.EqualTo(ex.Message)); } @@ -303,6 +303,43 @@ public async Task DbSetCreatedFromCollectionGetAllUserEntity() Assert.That(users.Count, Is.EqualTo(result.Count)); } + [TestCase] + public void GetUsersByFirstName_ExpressionVisitorMissing_ThrowsException() + { + // arrange + var users = CreateUserList(); + + var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); + + // act + var exception = Assert.ThrowsAsync(() => userRepository.GetUsersByFirstName("naME")); + + // assert + Assert.That( + exception.Message, + Is.EqualTo( + "The 'ILike' method is not supported because the query has switched to client-evaluation. " + + "This usually happens when the arguments to the method cannot be translated to server. " + + "Rewrite the query to avoid client evaluation of arguments so that method can be translated to server.")); + } + + [TestCase] + public async Task GetUsersByFirstName_PartOfNameCaseInsensitiveSearch_AllMatchesReturned() + { + // arrange + var users = CreateUserList(); + + var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); + + // act + var result = await userRepository.GetUsersByFirstName("naME"); + + // assert + Assert.That(users.Count, Is.EqualTo(result.Count())); + } + private static List CreateUserList() => new() { new UserEntity diff --git a/src/MockQueryable/MockQueryable.Sample/MyServiceMoqTests.cs b/src/MockQueryable/MockQueryable.Sample/MyServiceMoqTests.cs index d597ac0..99da01d 100644 --- a/src/MockQueryable/MockQueryable.Sample/MyServiceMoqTests.cs +++ b/src/MockQueryable/MockQueryable.Sample/MyServiceMoqTests.cs @@ -61,8 +61,6 @@ public async Task GetUserReports(DateTime from, DateTime to, int expectedCount) Assert.That(expectedCount, Is.EqualTo(result.Count)); } - - [TestCase("01/20/2012", "06/20/2018", 5)] [TestCase("01/20/2012", "06/20/2012", 4)] [TestCase("01/20/2012", "02/20/2012", 3)] @@ -82,7 +80,6 @@ public async Task GetUserReports_AutoMap(DateTime from, DateTime to, int expecte Assert.That(expectedCount, Is.EqualTo(result.Count)); } - [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] @@ -281,7 +278,6 @@ public async Task DbSetFindAsyncUserEntity() Assert.That("FirstName3", Is.EqualTo(result.FirstName)); } - [TestCase] public async Task DbSetCreatedFromCollectionFindAsyncUserEntity() { @@ -348,7 +344,6 @@ public async Task DbSetGetAllUserEntitiesAsync() Assert.That(users.Count, Is.EqualTo(result.Count)); } - [TestCase] public async Task DbSetToListAsyncAsync_ShouldReturnAllEntities_WhenSourceIsChanged() { @@ -367,8 +362,6 @@ public async Task DbSetToListAsyncAsync_ShouldReturnAllEntities_WhenSourceIsChan Assert.That(users.Count, Is.EqualTo(result2.Count)); } - - [TestCase] public async Task DbSetCreatedFromCollectionGetAllUserEntitiesAsync() { @@ -385,6 +378,43 @@ public async Task DbSetCreatedFromCollectionGetAllUserEntitiesAsync() Assert.That(users.Count, Is.EqualTo(result.Count)); } + [TestCase] + public void GetUsersByFirstName_ExpressionVisitorMissing_ThrowsException() + { + // arrange + var users = CreateUserList(); + + var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet.Object); + + // act + var exception = Assert.ThrowsAsync(() => userRepository.GetUsersByFirstName("naME")); + + // assert + Assert.That( + exception.Message, + Is.EqualTo( + "The 'ILike' method is not supported because the query has switched to client-evaluation. " + + "This usually happens when the arguments to the method cannot be translated to server. " + + "Rewrite the query to avoid client evaluation of arguments so that method can be translated to server.")); + } + + [TestCase] + public async Task GetUsersByFirstName_PartOfNameCaseInsensitiveSearch_AllMatchesReturned() + { + // arrange + var users = CreateUserList(); + + var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet.Object); + + // act + var result = await userRepository.GetUsersByFirstName("naME"); + + // assert + Assert.That(users.Count, Is.EqualTo(result.Count())); + } + private static List CreateUserList() => new() { new UserEntity { FirstName = "FirstName1", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, diff --git a/src/MockQueryable/MockQueryable.Sample/MyServiceNSubstituteTests.cs b/src/MockQueryable/MockQueryable.Sample/MyServiceNSubstituteTests.cs index 4a1ccb9..b9b8509 100644 --- a/src/MockQueryable/MockQueryable.Sample/MyServiceNSubstituteTests.cs +++ b/src/MockQueryable/MockQueryable.Sample/MyServiceNSubstituteTests.cs @@ -37,7 +37,6 @@ public void CreateUserIfNotExist(string firstName, string lastName, DateTime dat var ex = Assert.ThrowsAsync(() => service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); //assert Assert.That(expectedError, Is.EqualTo(ex.Message)); - } [TestCase("01/20/2012", "06/20/2018", 5)] @@ -331,6 +330,43 @@ public async Task DbSetCreatedFromCollectionGetOneUserTntityAsync() Assert.That(users.First(), Is.EqualTo(result)); } + [TestCase] + public void GetUsersByFirstName_ExpressionVisitorMissing_ThrowsException() + { + // arrange + var users = CreateUserList(); + + var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); + + // act + var exception = Assert.ThrowsAsync(() => userRepository.GetUsersByFirstName("naME")); + + // assert + Assert.That( + exception.Message, + Is.EqualTo( + "The 'ILike' method is not supported because the query has switched to client-evaluation. " + + "This usually happens when the arguments to the method cannot be translated to server. " + + "Rewrite the query to avoid client evaluation of arguments so that method can be translated to server.")); + } + + [TestCase] + public async Task GetUsersByFirstName_PartOfNameCaseInsensitiveSearch_AllMatchesReturned() + { + // arrange + var users = CreateUserList(); + + var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); + + // act + var result = await userRepository.GetUsersByFirstName("naME"); + + // assert + Assert.That(users.Count, Is.EqualTo(result.Count())); + } + private static List CreateUserList() => new() { new UserEntity { FirstName = "FirstName1", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, diff --git a/src/MockQueryable/MockQueryable.Sample/SampleILikeExpressionVisitor .cs b/src/MockQueryable/MockQueryable.Sample/SampleILikeExpressionVisitor .cs new file mode 100644 index 0000000..53c2bf7 --- /dev/null +++ b/src/MockQueryable/MockQueryable.Sample/SampleILikeExpressionVisitor .cs @@ -0,0 +1,40 @@ +using Microsoft.EntityFrameworkCore; +using System; +using System.Linq.Expressions; + +namespace MockQueryable.Sample +{ + public class SampleILikeExpressionVisitor : ExpressionVisitor + { + private static readonly char[] value = ['%']; + + /// + /// Rewrites the ILike method call to a string.Contains call with a trimmed + /// and lowercased pattern. + /// This is used to simulate the behavior of ILike in PostgreSQL, which is + /// case-insensitive and allows for wildcard matching with '%'. + /// + protected override Expression VisitMethodCall(MethodCallExpression node) + { + if (node.Method.Name != nameof(NpgsqlDbFunctionsExtensions.ILike) || + node.Arguments.Count != 3) + { + return base.VisitMethodCall(node); + } + + var stringExpression = node.Arguments[1]; + var patternExpression = node.Arguments[2]; + + var toLowerPattern = Expression.Call(patternExpression, nameof(string.ToLower), Type.EmptyTypes); + var trimMethod = typeof(string).GetMethod(nameof(string.Trim), [typeof(char[])]); + var trimmedPattern = Expression.Call(toLowerPattern, trimMethod!, Expression.Constant(value)); + + return Expression.Call( + Expression.Call(stringExpression, nameof(string.ToLower), Type.EmptyTypes), + nameof(string.Contains), + Type.EmptyTypes, + trimmedPattern + ); + } + } +} diff --git a/src/MockQueryable/MockQueryable.Sample/TestDbSetRepository.cs b/src/MockQueryable/MockQueryable.Sample/TestDbSetRepository.cs index 59266d0..db72a66 100644 --- a/src/MockQueryable/MockQueryable.Sample/TestDbSetRepository.cs +++ b/src/MockQueryable/MockQueryable.Sample/TestDbSetRepository.cs @@ -5,31 +5,40 @@ namespace MockQueryable.Sample { - public class TestDbSetRepository : IUserRepository + public class TestDbSetRepository : IUserRepository + { + private readonly DbSet _dbSet; + + public TestDbSetRepository(DbSet dbSet) + { + _dbSet = dbSet; + } + + public IQueryable GetQueryable() { - private readonly DbSet _dbSet; + return _dbSet; + } - public TestDbSetRepository(DbSet dbSet) - { - _dbSet = dbSet; - } - public IQueryable GetQueryable() - { - return _dbSet; - } + public async Task CreateUser(UserEntity user) + { + await _dbSet.AddAsync(user); + } - public async Task CreateUser(UserEntity user) - { - await _dbSet.AddAsync(user); - } + public async Task> GetAll() + { + return await _dbSet.ToListAsync(); + } - public async Task> GetAll() { - return await _dbSet.ToListAsync(); - } + public IAsyncEnumerable GetAllAsync() + { + return _dbSet.AsAsyncEnumerable(); + } - public IAsyncEnumerable GetAllAsync() - { - return _dbSet.AsAsyncEnumerable(); - } + public async Task> GetUsersByFirstName(string firstName) + { + return await _dbSet + .Where(x => EF.Functions.ILike(x.FirstName, $"%{firstName}%")) + .ToListAsync(); } + } } \ No newline at end of file From 1af184298fe74b7e65b212933f7cb26bfd9504c4 Mon Sep 17 00:00:00 2001 From: Catlandor Date: Tue, 22 Jul 2025 23:45:13 +0200 Subject: [PATCH 6/8] #66: Adjust test data set for `ExecuteUpdateAsync` and `ExecuteDeleteAsync` --- .../MockQueryable.Core/TestQueryProvider.cs | 147 ++-- .../MockQueryableExtensions.cs | 10 +- .../TestQueryProviderEfCore.cs | 81 +- .../FakeItEasyExtensions.cs | 144 ++-- .../MockQueryable.Moq/MoqExtensions.cs | 146 ++-- .../NSubstituteExtensions.cs | 37 +- .../MockQueryable.Sample/MyService.cs | 2 +- .../MyServiceFakeItEasyTests.cs | 250 +++--- .../MockQueryable.Sample/MyServiceMoqTests.cs | 661 ++++++++-------- .../MyServiceNSubstituteTests.cs | 730 +++++++++--------- .../TestDbSetRepository.cs | 65 +- 11 files changed, 1247 insertions(+), 1026 deletions(-) diff --git a/src/MockQueryable/MockQueryable.Core/TestQueryProvider.cs b/src/MockQueryable/MockQueryable.Core/TestQueryProvider.cs index 4151f07..5884860 100644 --- a/src/MockQueryable/MockQueryable.Core/TestQueryProvider.cs +++ b/src/MockQueryable/MockQueryable.Core/TestQueryProvider.cs @@ -6,80 +6,81 @@ namespace MockQueryable.Core { - public abstract class TestQueryProvider : IOrderedQueryable, IQueryProvider + public abstract class TestQueryProvider : IOrderedQueryable, IQueryProvider + { + private IEnumerable _enumerable; + private readonly Action _optionalRemoveCallback; + + protected TestQueryProvider(Expression expression) + { + Expression = expression; + } + + protected TestQueryProvider(IEnumerable enumerable, Action optionalRemoveCallback) + { + _enumerable = enumerable; + Expression = enumerable.AsQueryable().Expression; + _optionalRemoveCallback = optionalRemoveCallback; + } + + public IQueryable CreateQuery(Expression expression) + { + if (expression is MethodCallExpression m) + { + var resultType = m.Method.ReturnType; // it should be IQueryable + var tElement = resultType.GetGenericArguments().First(); + return (IQueryable)CreateInstance(tElement, expression); + } + + return CreateQuery(expression); + } + + public IQueryable CreateQuery(Expression expression) + { + return (IQueryable)CreateInstance(typeof(TEntity), expression); + } + + private object CreateInstance(Type tElement, Expression expression) { + var queryType = GetType().GetGenericTypeDefinition().MakeGenericType(tElement); + return Activator.CreateInstance(queryType, expression, _optionalRemoveCallback); + } - private IEnumerable _enumerable; - - protected TestQueryProvider(Expression expression) - { - Expression = expression; - } - - protected TestQueryProvider(IEnumerable enumerable) - { - _enumerable = enumerable; - Expression = enumerable.AsQueryable().Expression; - } - - public IQueryable CreateQuery(Expression expression) - { - if (expression is MethodCallExpression m) - { - var resultType = m.Method.ReturnType; // it should be IQueryable - var tElement = resultType.GetGenericArguments().First(); - return (IQueryable) CreateInstance(tElement, expression); - } - - return CreateQuery(expression); - } - - public IQueryable CreateQuery(Expression expression) - { - return (IQueryable) CreateInstance(typeof(TEntity), expression); - } - - private object CreateInstance(Type tElement, Expression expression) - { - var queryType = GetType().GetGenericTypeDefinition().MakeGenericType(tElement); - return Activator.CreateInstance(queryType, expression); - } - - public object Execute(Expression expression) - { - return CompileExpressionItem(expression); - } - - public virtual TResult Execute(Expression expression) - { - - return CompileExpressionItem(expression); - } - - IEnumerator IEnumerable.GetEnumerator() - { - if (_enumerable == null) _enumerable = CompileExpressionItem>(Expression); - return _enumerable.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - if (_enumerable == null) _enumerable = CompileExpressionItem>(Expression); - return _enumerable.GetEnumerator(); - } - - public Type ElementType => typeof(T); - - public Expression Expression { get; } - - public IQueryProvider Provider => this; - - protected static TResult CompileExpressionItem(Expression expression) - { - var visitor = new TestExpressionVisitor(); - var body = visitor.Visit(expression); - var f = Expression.Lambda>(body ?? throw new InvalidOperationException($"{nameof(body)} is null"), (IEnumerable) null); - return f.Compile()(); - } + public object Execute(Expression expression) + { + return CompileExpressionItem(expression); + } + + public virtual TResult Execute(Expression expression) + { + + return CompileExpressionItem(expression); + } + + IEnumerator IEnumerable.GetEnumerator() + { + if (_enumerable == null) _enumerable = CompileExpressionItem>(Expression); + return _enumerable.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + if (_enumerable == null) _enumerable = CompileExpressionItem>(Expression); + return _enumerable.GetEnumerator(); + } + + public Type ElementType => typeof(T); + + public Expression Expression { get; } + + public IQueryProvider Provider => this; + + protected static TResult CompileExpressionItem(Expression expression) + { + var visitor = new TestExpressionVisitor(); + var body = visitor.Visit(expression); + var f = Expression.Lambda>(body ?? throw new InvalidOperationException($"{nameof(body)} is null"), (IEnumerable)null); + return f.Compile()(); } + } } \ No newline at end of file diff --git a/src/MockQueryable/MockQueryable.EntityFrameworkCore/MockQueryableExtensions.cs b/src/MockQueryable/MockQueryable.EntityFrameworkCore/MockQueryableExtensions.cs index c94b1c8..5082190 100644 --- a/src/MockQueryable/MockQueryable.EntityFrameworkCore/MockQueryableExtensions.cs +++ b/src/MockQueryable/MockQueryable.EntityFrameworkCore/MockQueryableExtensions.cs @@ -9,11 +9,11 @@ // is dependent on the EF Core AsyncEnumerable. namespace MockQueryable { - public static class MockQueryableExtensions + public static class MockQueryableExtensions + { + public static IQueryable BuildMock(this IEnumerable data) where TEntity : class { - public static IQueryable BuildMock(this IEnumerable data) where TEntity : class - { - return new TestAsyncEnumerableEfCore(data); - } + return new TestAsyncEnumerableEfCore(data); } + } } diff --git a/src/MockQueryable/MockQueryable.EntityFrameworkCore/TestQueryProviderEfCore.cs b/src/MockQueryable/MockQueryable.EntityFrameworkCore/TestQueryProviderEfCore.cs index 7da4937..4569c5c 100644 --- a/src/MockQueryable/MockQueryable.EntityFrameworkCore/TestQueryProviderEfCore.cs +++ b/src/MockQueryable/MockQueryable.EntityFrameworkCore/TestQueryProviderEfCore.cs @@ -1,25 +1,30 @@ -using System.Collections.Generic; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Query; +using MockQueryable.Core; +using System; +using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Query; -using MockQueryable.Core; namespace MockQueryable.EntityFrameworkCore { - public class TestAsyncEnumerableEfCore: TestQueryProvider, IAsyncEnumerable, IAsyncQueryProvider + public class TestAsyncEnumerableEfCore : TestQueryProvider, IAsyncEnumerable, IAsyncQueryProvider { - public TestAsyncEnumerableEfCore(Expression expression) : base(expression) + private readonly Action _optionalRemoveCallback; + + public TestAsyncEnumerableEfCore(Expression expression, Action optionalRemoveCallback = null) : base(expression) { + _optionalRemoveCallback = optionalRemoveCallback; } - public TestAsyncEnumerableEfCore(IEnumerable enumerable) : base(enumerable) + public TestAsyncEnumerableEfCore(IEnumerable enumerable, Action optionalRemoveCallback = null) : base(enumerable, optionalRemoveCallback) { + _optionalRemoveCallback = optionalRemoveCallback; } - public TResult ExecuteAsync(Expression expression, CancellationToken cancellationToken) + public TResult ExecuteAsync(Expression expression, CancellationToken cancellationToken = default) { var expectedResultType = typeof(TResult).GetGenericArguments()[0]; var executionResult = typeof(IQueryProvider) @@ -35,22 +40,64 @@ public TResult ExecuteAsync(Expression expression, CancellationToken ca public override TResult Execute(Expression expression) { - if (expression is MethodCallExpression methodCall && (methodCall.Method.Name == nameof(RelationalQueryableExtensions.ExecuteUpdate) || methodCall.Method.Name == nameof(RelationalQueryableExtensions.ExecuteDelete) ) - && typeof(TResult) == typeof(int)) + // Intercept ExecuteDelete and ExecuteUpdate calls + if (expression is MethodCallExpression methodCall && + (methodCall.Method.Name == nameof(RelationalQueryableExtensions.ExecuteUpdate) || methodCall.Method.Name == nameof(RelationalQueryableExtensions.ExecuteDelete)) && + typeof(TResult) == typeof(int)) + { + var affectedItems = base.Execute>(Expression).ToList(); + + if (methodCall.Method.Name == nameof(RelationalQueryableExtensions.ExecuteUpdate)) { - // Intercept ExecuteDelete and ExecuteUpdate calls - var affectedItems = base.Execute>(Expression).ToList(); - - // Return the count of affected items - return (TResult)(object)affectedItems.Count; + ApplyUpdateChangesToDbSet(affectedItems, methodCall); } - // Fall back to default expression execution - return base.Execute(expression); + + if (methodCall.Method.Name == nameof(RelationalQueryableExtensions.ExecuteDelete)) + { + foreach (var item in affectedItems) + { + _optionalRemoveCallback?.Invoke(item); + } + } + + // Return the count of affected items + return (TResult)(object)affectedItems.Count; + } + // Fall back to default expression execution + return base.Execute(expression); } public IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) { return new TestAsyncEnumerator(this.AsEnumerable().GetEnumerator()); } + + private static void ApplyUpdateChangesToDbSet(IEnumerable affectedItems, MethodCallExpression methodCallExpression) + { + // Extract the update lambda: opt => opt.SetProperty(...) + if ((methodCallExpression.Arguments[1] as UnaryExpression)?.Operand is not LambdaExpression updateLambda) + { + return; + } + + // The body may be a chain of MethodCallExpressions + var currentCall = updateLambda.Body as MethodCallExpression; + while (currentCall != null && currentCall.Method.Name == "SetProperty") + { + var memberExpr = currentCall.Arguments[0] as LambdaExpression; + var valueExpr = currentCall.Arguments[1]; + + var propertyInfo = ((memberExpr.Body as MemberExpression)?.Member) as System.Reflection.PropertyInfo; + var value = Expression.Lambda(valueExpr).Compile().DynamicInvoke(); + + foreach (var item in affectedItems) + { + propertyInfo?.SetValue(item, value); + } + + // Move to the next chained call (if any) + currentCall = currentCall.Object as MethodCallExpression; + } + } } } diff --git a/src/MockQueryable/MockQueryable.FakeItEasy/FakeItEasyExtensions.cs b/src/MockQueryable/MockQueryable.FakeItEasy/FakeItEasyExtensions.cs index ee8c1b0..181ba0d 100644 --- a/src/MockQueryable/MockQueryable.FakeItEasy/FakeItEasyExtensions.cs +++ b/src/MockQueryable/MockQueryable.FakeItEasy/FakeItEasyExtensions.cs @@ -8,61 +8,95 @@ namespace MockQueryable.FakeItEasy { - public static class FakeItEasyExtensions + public static class FakeItEasyExtensions + { + public static DbSet BuildMockDbSet(this IEnumerable data) where TEntity : class => data.BuildMock().BuildMockDbSet(); + + public static DbSet BuildMockDbSet(this IQueryable data) where TEntity : class + { + var mock = A.Fake>(d => d.Implements>().Implements>()); + var enumerable = new TestAsyncEnumerableEfCore(data); + + ConfigureAllCalls(mock, enumerable, data); + + return mock; + } + + public static DbSet BuildMockDbSetWithInterceptedExecuteDelete( + this ICollection data) where TEntity : class + { + var mock = A.Fake>(d => d.Implements>().Implements>()); + var enumerable = new TestAsyncEnumerableEfCore(data, x => data.Remove(x)); + + ConfigureAllCalls(mock, enumerable, data.AsQueryable()); + + return mock; + } + + public static DbSet BuildMockDbSetWithInterceptedExecuteDelete( + this DbSet data) where TEntity : class + { + var mock = A.Fake>(d => d.Implements>().Implements>()); + var enumerable = new TestAsyncEnumerableEfCore(data, x => data.Remove(x)); + + ConfigureAllCalls(mock, enumerable, data); + + return mock; + } + + private static void ConfigureAllCalls( + this DbSet mock, + TestAsyncEnumerableEfCore enumerable, + IQueryable data) where TEntity : class { - public static DbSet BuildMockDbSet(this IEnumerable data) where TEntity : class => data.BuildMock().BuildMockDbSet(); - - public static DbSet BuildMockDbSet(this IQueryable data) where TEntity : class - { - var mock = A.Fake>(d => d.Implements>().Implements>()); - var enumerable = new TestAsyncEnumerableEfCore(data); - mock.ConfigureQueryableCalls(enumerable, data); - mock.ConfigureAsyncEnumerableCalls(enumerable); - mock.ConfigureDbSetCalls(data); - if (mock is IAsyncEnumerable asyncEnumerable) - { - A.CallTo(() => asyncEnumerable.GetAsyncEnumerator(A.Ignored)).ReturnsLazily(() => enumerable.GetAsyncEnumerator()); - } - return mock; - } - - - private static void ConfigureQueryableCalls( - this IQueryable mock, - IQueryProvider queryProvider, - IQueryable data) where TEntity : class - { - A.CallTo(() => mock.Provider).Returns(queryProvider); - A.CallTo(() => mock.Expression).Returns(data?.Expression); - A.CallTo(() => mock.ElementType).Returns(data?.ElementType); - A.CallTo(() => mock.GetEnumerator()).ReturnsLazily(() => data?.GetEnumerator()); - } - - private static void ConfigureAsyncEnumerableCalls( - this DbSet mock, - IAsyncEnumerable enumerable) where TEntity : class - { - A.CallTo(() => mock.GetAsyncEnumerator(A.Ignored)) - .Returns(enumerable.GetAsyncEnumerator()); - - } - - private static void ConfigureDbSetCalls(this DbSet mock, IQueryable data) - where TEntity : class - { - A.CallTo(() => mock.AsQueryable()).Returns(data); - A.CallTo(() => mock.AsAsyncEnumerable()).ReturnsLazily(args => CreateAsyncMock(data)); - } - - private static async IAsyncEnumerable CreateAsyncMock(IEnumerable data) - where TEntity : class - { - foreach (var entity in data) - { - yield return entity; - } - - await Task.CompletedTask; - } + mock.ConfigureQueryableCalls(enumerable, data); + mock.ConfigureAsyncEnumerableCalls(enumerable); + mock.ConfigureDbSetCalls(data); + if (mock is IAsyncEnumerable asyncEnumerable) + { + A.CallTo(() => asyncEnumerable.GetAsyncEnumerator(A.Ignored)).ReturnsLazily(() => enumerable.GetAsyncEnumerator()); + } + } + + private static void ConfigureQueryableCalls( + this IQueryable mock, + IQueryProvider queryProvider, + IQueryable data) where TEntity : class + { + A.CallTo(() => mock.Provider).Returns(queryProvider); + A.CallTo(() => mock.Expression).Returns(data?.Expression); + A.CallTo(() => mock.ElementType).Returns(data?.ElementType); + A.CallTo(() => mock.GetEnumerator()).ReturnsLazily(() => data?.GetEnumerator()); + } + + private static void ConfigureAsyncEnumerableCalls( + this DbSet mock, + IAsyncEnumerable enumerable) where TEntity : class + { + A.CallTo(() => mock.GetAsyncEnumerator(A.Ignored)) + .Returns(enumerable.GetAsyncEnumerator()); + + } + + private static void ConfigureDbSetCalls(this DbSet mock, IQueryable data) + where TEntity : class + { + A.CallTo(() => mock.AsQueryable()).Returns(data.AsQueryable()); + A.CallTo(() => mock.AsAsyncEnumerable()).ReturnsLazily(args => CreateAsyncMock(mock)); + } + + private static async IAsyncEnumerable CreateAsyncMock( + this IQueryable mock) + where TEntity : class + { + var data = await mock.ToListAsync(); + + foreach (var entity in data) + { + yield return entity; + } + + await Task.CompletedTask; } + } } \ No newline at end of file diff --git a/src/MockQueryable/MockQueryable.Moq/MoqExtensions.cs b/src/MockQueryable/MockQueryable.Moq/MoqExtensions.cs index dafd6b0..8d00d6e 100644 --- a/src/MockQueryable/MockQueryable.Moq/MoqExtensions.cs +++ b/src/MockQueryable/MockQueryable.Moq/MoqExtensions.cs @@ -8,61 +8,93 @@ namespace MockQueryable.Moq { - public static class MoqExtensions - { - - public static Mock> BuildMockDbSet(this IEnumerable data) where TEntity : class => data.BuildMock().BuildMockDbSet(); - - public static Mock> BuildMockDbSet(this IQueryable data) where TEntity : class - { - var mock = new Mock>(); - var enumerable = new TestAsyncEnumerableEfCore(data); - mock.ConfigureAsyncEnumerableCalls(enumerable); - mock.As>().ConfigureQueryableCalls(enumerable, data); - mock.As>().Setup(x => x.GetAsyncEnumerator(It.IsAny())).Returns(() => enumerable.GetAsyncEnumerator()); - mock.Setup(m => m.AsQueryable()).Returns(enumerable); - - mock.ConfigureDbSetCalls(data); - return mock; - } - - private static void ConfigureDbSetCalls(this Mock> mock, IQueryable data) - where TEntity : class - { - mock.Setup(m => m.AsQueryable()).Returns(mock.Object); - mock.Setup(m => m.AsAsyncEnumerable()).Returns(CreateAsyncMock(data)); - } - - private static void ConfigureQueryableCalls( - this Mock> mock, - IQueryProvider queryProvider, - IQueryable data) where TEntity : class - { - mock.Setup(m => m.Provider).Returns(queryProvider); - mock.Setup(m => m.Expression).Returns(data?.Expression); - mock.Setup(m => m.ElementType).Returns(data?.ElementType); - mock.Setup(m => m.GetEnumerator()).Returns(() => data?.GetEnumerator()); - - } - - private static void ConfigureAsyncEnumerableCalls( - this Mock> mock, - IAsyncEnumerable enumerable)where TEntity : class - { - mock.Setup(d => d.GetAsyncEnumerator(It.IsAny())) - .Returns(() => enumerable.GetAsyncEnumerator()); - - } - - private static async IAsyncEnumerable CreateAsyncMock(IEnumerable data) - where TEntity : class - { - foreach (var entity in data) - { - yield return entity; - } - - await Task.CompletedTask; - } - } + public static class MoqExtensions + { + + public static Mock> BuildMockDbSet(this IEnumerable data) where TEntity : class => data.BuildMock().BuildMockDbSet(); + + public static Mock> BuildMockDbSet(this IQueryable data) where TEntity : class + { + var mock = new Mock>(); + var enumerable = new TestAsyncEnumerableEfCore(data); + + ConfigureAllCalls(mock, enumerable, data); + + return mock; + } + + public static Mock> BuildMockDbSetWithInterceptedExecuteDelete( + this ICollection data) where TEntity : class + { + var mock = new Mock>(); + var enumerable = new TestAsyncEnumerableEfCore(data, x => data.Remove(x)); + + ConfigureAllCalls(mock, enumerable, data.AsQueryable()); + + return mock; + } + + public static Mock> BuildMockDbSetWithInterceptedExecuteDelete( + this DbSet data) where TEntity : class + { + var mock = new Mock>(); + var enumerable = new TestAsyncEnumerableEfCore(data, x => data.Remove(x)); + + ConfigureAllCalls(mock, enumerable, data.AsQueryable()); + + return mock; + } + + private static void ConfigureAllCalls( + this Mock> mock, + TestAsyncEnumerableEfCore enumerable, + IQueryable data) where TEntity : class + { + mock.ConfigureAsyncEnumerableCalls(enumerable); + mock.As>().ConfigureQueryableCalls(enumerable, data); + mock.As>().Setup(x => x.GetAsyncEnumerator(It.IsAny())).Returns(() => enumerable.GetAsyncEnumerator()); + mock.Setup(m => m.AsQueryable()).Returns(enumerable); + + mock.ConfigureDbSetCalls(data); + } + + private static void ConfigureDbSetCalls(this Mock> mock, IQueryable data) + where TEntity : class + { + mock.Setup(m => m.AsQueryable()).Returns(mock.Object); + mock.Setup(m => m.AsAsyncEnumerable()).Returns(CreateAsyncMock(data)); + } + + private static void ConfigureQueryableCalls( + this Mock> mock, + IQueryProvider queryProvider, + IQueryable data) where TEntity : class + { + mock.Setup(m => m.Provider).Returns(queryProvider); + mock.Setup(m => m.Expression).Returns(data?.Expression); + mock.Setup(m => m.ElementType).Returns(data?.ElementType); + mock.Setup(m => m.GetEnumerator()).Returns(() => data?.GetEnumerator()); + + } + + private static void ConfigureAsyncEnumerableCalls( + this Mock> mock, + IAsyncEnumerable enumerable) where TEntity : class + { + mock.Setup(d => d.GetAsyncEnumerator(It.IsAny())) + .Returns(() => enumerable.GetAsyncEnumerator()); + + } + + private static async IAsyncEnumerable CreateAsyncMock(IEnumerable data) + where TEntity : class + { + foreach (var entity in data) + { + yield return entity; + } + + await Task.CompletedTask; + } + } } \ No newline at end of file diff --git a/src/MockQueryable/MockQueryable.NSubstitute/NSubstituteExtensions.cs b/src/MockQueryable/MockQueryable.NSubstitute/NSubstituteExtensions.cs index 0db0998..9357eeb 100644 --- a/src/MockQueryable/MockQueryable.NSubstitute/NSubstituteExtensions.cs +++ b/src/MockQueryable/MockQueryable.NSubstitute/NSubstituteExtensions.cs @@ -17,19 +17,48 @@ public static DbSet BuildMockDbSet(this IQueryable da var mock = Substitute.For, IQueryable, IAsyncEnumerable>(); var enumerable = new TestAsyncEnumerableEfCore(data); + ConfigureAllCalls(mock, enumerable, data); + + return mock; + } + + public static DbSet BuildMockDbSetWithInterceptedExecuteDelete( + this ICollection data) where TEntity : class + { + var mock = Substitute.For, IQueryable, IAsyncEnumerable>(); + var enumerable = new TestAsyncEnumerableEfCore(data, x => data.Remove(x)); + + ConfigureAllCalls(mock, enumerable, data.AsQueryable()); + + return mock; + } + + public static DbSet BuildMockDbSetWithInterceptedExecuteDelete( + this DbSet data) where TEntity : class + { + var mock = Substitute.For, IQueryable, IAsyncEnumerable>(); + var enumerable = new TestAsyncEnumerableEfCore(data, x => data.Remove(x)); + + ConfigureAllCalls(mock, enumerable, data.AsQueryable()); + + return mock; + } + + private static void ConfigureAllCalls( + this DbSet mock, + TestAsyncEnumerableEfCore enumerable, + IQueryable data) where TEntity : class + { mock.ConfigureAsyncEnumerableCalls(enumerable); mock.ConfigureQueryableCalls(enumerable, data); mock.ConfigureDbSetCalls(data); if (mock is IAsyncEnumerable asyncEnumerable) { - asyncEnumerable.GetAsyncEnumerator(Arg.Any()).Returns(args => enumerable.GetAsyncEnumerator()); + asyncEnumerable.GetAsyncEnumerator(Arg.Any()).Returns(args => enumerable.GetAsyncEnumerator()); } - - return mock; } - private static void ConfigureQueryableCalls( this IQueryable mock, IQueryProvider queryProvider, diff --git a/src/MockQueryable/MockQueryable.Sample/MyService.cs b/src/MockQueryable/MockQueryable.Sample/MyService.cs index aa4a159..d07aa1b 100644 --- a/src/MockQueryable/MockQueryable.Sample/MyService.cs +++ b/src/MockQueryable/MockQueryable.Sample/MyService.cs @@ -92,7 +92,7 @@ public interface IUserRepository Task DeleteUserAsync(Guid id); - Task UpdateFirstNameByIdAsync(Guid id, string firstName); + Task UpdateFirstAndLastNameByIdAsync(Guid id, string firstName); } public class UserReport diff --git a/src/MockQueryable/MockQueryable.Sample/MyServiceFakeItEasyTests.cs b/src/MockQueryable/MockQueryable.Sample/MyServiceFakeItEasyTests.cs index c32a12f..0f62a82 100644 --- a/src/MockQueryable/MockQueryable.Sample/MyServiceFakeItEasyTests.cs +++ b/src/MockQueryable/MockQueryable.Sample/MyServiceFakeItEasyTests.cs @@ -1,13 +1,13 @@ -using System; +using FakeItEasy; +using Microsoft.EntityFrameworkCore; +using MockQueryable.FakeItEasy; +using NUnit.Framework; +using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Threading; using System.Threading.Tasks; -using FakeItEasy; -using Microsoft.EntityFrameworkCore; -using MockQueryable.FakeItEasy; -using NUnit.Framework; namespace MockQueryable.Sample { @@ -115,8 +115,8 @@ public void DbSetCreateUserIfNotExist(string firstName, string lastName, DateTim [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] public void DbSetCreatedFromCollectionCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) { - //arrange - var users = new List + //arrange + var users = new List { new UserEntity {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, new UserEntity {FirstName = "ExistFirstName"}, @@ -124,14 +124,14 @@ public void DbSetCreatedFromCollectionCreateUserIfNotExist(string firstName, str new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, }; - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - //act - var ex = Assert.ThrowsAsync(() => - service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); - //assert - Assert.AreEqual(expectedError, ex.Message); + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + //act + var ex = Assert.ThrowsAsync(() => + service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); + //assert + Assert.AreEqual(expectedError, ex.Message); } @@ -144,7 +144,7 @@ public async Task DbSetCreateUser(string firstName, string lastName, DateTime da A.CallTo(() => mock.AddAsync(A._, A._)) .ReturnsLazily(call => { - userEntities.Add((UserEntity) call.Arguments[0]); + userEntities.Add((UserEntity)call.Arguments[0]); return default; }); var userRepository = new TestDbSetRepository(mock); @@ -161,24 +161,24 @@ public async Task DbSetCreateUser(string firstName, string lastName, DateTime da [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] public async Task DbSetCreatedFromCollectionCreateUser1(string firstName, string lastName, DateTime dateOfBirth) { - //arrange - var userEntities = new List(); - var mock = userEntities.BuildMockDbSet(); - A.CallTo(() => mock.AddAsync(A._, A._)) - .ReturnsLazily(call => - { - userEntities.Add((UserEntity)call.Arguments[0]); - return default; - }); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - //act - await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); - // assert - var entity = mock.Single(); - Assert.AreEqual(firstName, entity.FirstName); - Assert.AreEqual(lastName, entity.LastName); - Assert.AreEqual(dateOfBirth, entity.DateOfBirth); + //arrange + var userEntities = new List(); + var mock = userEntities.BuildMockDbSet(); + A.CallTo(() => mock.AddAsync(A._, A._)) + .ReturnsLazily(call => + { + userEntities.Add((UserEntity)call.Arguments[0]); + return default; + }); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + //act + await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); + // assert + var entity = mock.Single(); + Assert.AreEqual(firstName, entity.FirstName); + Assert.AreEqual(lastName, entity.LastName); + Assert.AreEqual(dateOfBirth, entity.DateOfBirth); } [TestCase("01/20/2012", "06/20/2018", 5)] @@ -204,15 +204,15 @@ public async Task DbSetGetUserReports(DateTime from, DateTime to, int expectedCo [TestCase("01/20/2010", "02/20/2011", 0)] public async Task DbSetCreatedFromCollectionGetUserReports(DateTime from, DateTime to, int expectedCount) { - //arrange - var users = CreateUserList(); - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - //act - var result = await service.GetUserReports(from, to); - //assert - Assert.AreEqual(expectedCount, result.Count); + //arrange + var users = CreateUserList(); + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + //act + var result = await service.GetUserReports(from, to); + //assert + Assert.AreEqual(expectedCount, result.Count); } [Test] @@ -234,31 +234,32 @@ public async Task DbSetGetAllUserEntitiesAsync() [Test] public async Task DbSetCreatedFromCollectionGetAllUserEntitiesAsync() { - // arrange - var users = CreateUserList(); + // arrange + var users = CreateUserList(); - var mockDbSet = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet); + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); - // act - var result = await userRepository.GetAllAsync().ToListAsync(); + // act + var result = await userRepository.GetAllAsync().ToListAsync(); - // assert - Assert.AreEqual(users.Count, result.Count); + // assert + Assert.AreEqual(users.Count, result.Count); } [Test] - public async Task DbSetToListAsyncAsync_ShouldReturnAllEntities_WhenSourceIsChanged() + public async Task DbSetGetAllUserEntitiesAsync_ShouldReturnAllEntities_WhenSourceIsChanged() { // arrange var users = new List(); var mockDbSet = users.AsQueryable().BuildMockDbSet(); - + var userRepository = new TestDbSetRepository(mockDbSet); + // act - var result1 = await mockDbSet.ToListAsync(); + var result1 = await userRepository.GetAllAsync().ToListAsync(); users.AddRange(CreateUserList()); - var result2 = await mockDbSet.ToListAsync(); + var result2 = await userRepository.GetAllAsync().ToListAsync(); // assert Assert.AreEqual(0, result1.Count); @@ -268,97 +269,122 @@ public async Task DbSetToListAsyncAsync_ShouldReturnAllEntities_WhenSourceIsChan [Test] public async Task DbSetGetAllUserEntity() { - //arrange - var users = CreateUserList(); - var mock = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - //act - var result = await userRepository.GetAll(); - //assert - Assert.AreEqual(users.Count, result.Count); + //arrange + var users = CreateUserList(); + var mock = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + //act + var result = await userRepository.GetAll(); + //assert + Assert.AreEqual(users.Count, result.Count); } [Test] public async Task DbSetCreatedFromCollectionGetAllUserEntity() { - //arrange - var users = CreateUserList(); - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - //act - var result = await userRepository.GetAll(); - //assert - Assert.AreEqual(users.Count, result.Count); + //arrange + var users = CreateUserList(); + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + //act + var result = await userRepository.GetAll(); + //assert + Assert.AreEqual(users.Count, result.Count); } - [Test] - public async Task DbSetCreatedFromCollectionExecuteDeleteAsync() + public async Task DbSetCreatedFromCollection_ExecuteDeleteAsync_NoInterceptionEntityNotRemoved() { - // arrange - var userId = Guid.NewGuid(); - var users = CreateUserList(userId); + // arrange + var userId = Guid.NewGuid(); + var users = CreateUserList(userId); - var mockDbSet = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet); + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); - // act - var count = await userRepository.DeleteUserAsync(userId); + // act + var count = await userRepository.DeleteUserAsync(userId); - // assert - Assert.AreEqual(1, count); + // assert + Assert.AreEqual(1, count); + var updatedUsers = await userRepository.GetAllAsync().ToListAsync(); + Assert.IsNotNull(updatedUsers.SingleOrDefault(x => x.Id == userId)); + } + [Test] + public async Task DbSetCreatedFromCollection_ExecuteDeleteAsync_InterceptionEntityRemoved() + { + // arrange + var userId = Guid.NewGuid(); + var users = CreateUserList(userId); + + var mockDbSet = users.BuildMockDbSetWithInterceptedExecuteDelete(); + var userRepository = new TestDbSetRepository(mockDbSet); + + // act + var count = await userRepository.DeleteUserAsync(userId); + + // assert + Assert.AreEqual(1, count); + var updatedUsers = await userRepository.GetAllAsync().ToListAsync(); + Assert.IsNull(updatedUsers.SingleOrDefault(x => x.Id == userId)); } [Test] public async Task DbSetCreatedFromCollectionExecuteDeleteAsync_ShouldReturnZero() { - // arrange - var userId = Guid.NewGuid(); - var users = CreateUserList(userId); + // arrange + var userId = Guid.NewGuid(); + var users = CreateUserList(userId); - var mockDbSet = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet); + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); - //act - var count = await userRepository.DeleteUserAsync(Guid.NewGuid()); + //act + var count = await userRepository.DeleteUserAsync(Guid.NewGuid()); - // assert - Assert.AreEqual(0, count); + // assert + Assert.AreEqual(0, count); + var user = users.Single(x => x.Id == userId); + user.FirstName = "Unit Test"; + user.LastName = "Unit Test"; } [Test] public async Task DbSetCreatedFromCollectionExecuteUpdateAsync() { - // arrange - var userId = Guid.NewGuid(); - var users = CreateUserList(userId); - - var mockDbSet = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet); - - //act - var count = await userRepository.UpdateFirstNameByIdAsync(userId, "Unit Test"); - - //assert - Assert.AreEqual(1, count); + // arrange + var userId = Guid.NewGuid(); + var users = CreateUserList(userId); + + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); + + //act + var count = await userRepository.UpdateFirstAndLastNameByIdAsync(userId, "Unit Test"); + + //assert + Assert.AreEqual(1, count); + var user = users.Single(x => x.Id == userId); + user.FirstName = "Unit Test"; + user.LastName = "Unit Test"; } [Test] public async Task DbSetCreatedFromCollectionExecuteUpdateAsync_ShouldReturnZero() { - // arrange - var userId = Guid.NewGuid(); - var users = CreateUserList(userId); + // arrange + var userId = Guid.NewGuid(); + var users = CreateUserList(userId); - var mockDbSet = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet); + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); - //act - var count = await userRepository.UpdateFirstNameByIdAsync(Guid.NewGuid(), "Unit Test"); + //act + var count = await userRepository.UpdateFirstAndLastNameByIdAsync(Guid.NewGuid(), "Unit Test"); - //assert - Assert.AreEqual(0, count); + //assert + Assert.AreEqual(0, count); } private static List CreateUserList(Guid? userId = null) => new List diff --git a/src/MockQueryable/MockQueryable.Sample/MyServiceMoqTests.cs b/src/MockQueryable/MockQueryable.Sample/MyServiceMoqTests.cs index e1b0931..ebadf4d 100644 --- a/src/MockQueryable/MockQueryable.Sample/MyServiceMoqTests.cs +++ b/src/MockQueryable/MockQueryable.Sample/MyServiceMoqTests.cs @@ -11,20 +11,20 @@ namespace MockQueryable.Sample { - [TestFixture] - public class MyServiceMoqTests + [TestFixture] + public class MyServiceMoqTests + { + private static readonly CultureInfo UsCultureInfo = new CultureInfo("en-US"); + + [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] + [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] + [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] + public void CreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) { - private static readonly CultureInfo UsCultureInfo = new CultureInfo("en-US"); - - [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] - [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] - [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] - public void CreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) - { - //arrange - var userRepository = new Mock(); - var service = new MyService(userRepository.Object); - var users = new List + //arrange + var userRepository = new Mock(); + var service = new MyService(userRepository.Object); + var users = new List { new UserEntity {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, new UserEntity {FirstName = "ExistFirstName"}, @@ -32,64 +32,64 @@ public void CreateUserIfNotExist(string firstName, string lastName, DateTime dat new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)} }; - //expect - var mock = users.BuildMock(); - userRepository.Setup(x => x.GetQueryable()).Returns(mock); - //act - var ex = Assert.ThrowsAsync(() => - service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); - //assert - Assert.AreEqual(expectedError, ex.Message); - } + //expect + var mock = users.BuildMock(); + userRepository.Setup(x => x.GetQueryable()).Returns(mock); + //act + var ex = Assert.ThrowsAsync(() => + service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); + //assert + Assert.AreEqual(expectedError, ex.Message); + } - [TestCase("01/20/2012", "06/20/2018", 5)] - [TestCase("01/20/2012", "06/20/2012", 4)] - [TestCase("01/20/2012", "02/20/2012", 3)] - [TestCase("01/20/2010", "02/20/2011", 0)] - public async Task GetUserReports(DateTime from, DateTime to, int expectedCount) - { - //arrange - var userRepository = new Mock(); - var service = new MyService(userRepository.Object); - var users = CreateUserList(); - //expect - var mock = users.BuildMock(); - userRepository.Setup(x => x.GetQueryable()).Returns(mock); - //act - var result = await service.GetUserReports(from, to); - //assert - Assert.AreEqual(expectedCount, result.Count); - } + [TestCase("01/20/2012", "06/20/2018", 5)] + [TestCase("01/20/2012", "06/20/2012", 4)] + [TestCase("01/20/2012", "02/20/2012", 3)] + [TestCase("01/20/2010", "02/20/2011", 0)] + public async Task GetUserReports(DateTime from, DateTime to, int expectedCount) + { + //arrange + var userRepository = new Mock(); + var service = new MyService(userRepository.Object); + var users = CreateUserList(); + //expect + var mock = users.BuildMock(); + userRepository.Setup(x => x.GetQueryable()).Returns(mock); + //act + var result = await service.GetUserReports(from, to); + //assert + Assert.AreEqual(expectedCount, result.Count); + } - [TestCase("01/20/2012", "06/20/2018", 5)] - [TestCase("01/20/2012", "06/20/2012", 4)] - [TestCase("01/20/2012", "02/20/2012", 3)] - [TestCase("01/20/2010", "02/20/2011", 0)] - public async Task GetUserReports_AutoMap(DateTime from, DateTime to, int expectedCount) - { - //arrange - var userRepository = new Mock(); - var service = new MyService(userRepository.Object); - var users = CreateUserList(); - //expect - var mock = users.BuildMock(); - userRepository.Setup(x => x.GetQueryable()).Returns(mock); - //act - var result = await service.GetUserReportsAutoMap(from, to); - //assert - Assert.AreEqual(expectedCount, result.Count); - } + [TestCase("01/20/2012", "06/20/2018", 5)] + [TestCase("01/20/2012", "06/20/2012", 4)] + [TestCase("01/20/2012", "02/20/2012", 3)] + [TestCase("01/20/2010", "02/20/2011", 0)] + public async Task GetUserReports_AutoMap(DateTime from, DateTime to, int expectedCount) + { + //arrange + var userRepository = new Mock(); + var service = new MyService(userRepository.Object); + var users = CreateUserList(); + //expect + var mock = users.BuildMock(); + userRepository.Setup(x => x.GetQueryable()).Returns(mock); + //act + var result = await service.GetUserReportsAutoMap(from, to); + //assert + Assert.AreEqual(expectedCount, result.Count); + } - [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] - [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] - [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] - public void DbSetCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) - { - //arrange - var users = new List + [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] + [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] + [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] + public void DbSetCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) + { + //arrange + var users = new List { new UserEntity {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, new UserEntity {FirstName = "ExistFirstName"}, @@ -97,23 +97,23 @@ public void DbSetCreateUserIfNotExist(string firstName, string lastName, DateTim new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)} }; - var mock = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock.Object); - var service = new MyService(userRepository); - //act - var ex = Assert.ThrowsAsync(() => - service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); - //assert - Assert.AreEqual(expectedError, ex.Message); - } + var mock = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock.Object); + var service = new MyService(userRepository); + //act + var ex = Assert.ThrowsAsync(() => + service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); + //assert + Assert.AreEqual(expectedError, ex.Message); + } - [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] - [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] - [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] - public void DbSetCreatedFromCollectionCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) - { - //arrange - var users = new List + [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] + [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] + [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] + public void DbSetCreatedFromCollectionCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) + { + //arrange + var users = new List { new UserEntity {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, new UserEntity {FirstName = "ExistFirstName"}, @@ -121,122 +121,122 @@ public void DbSetCreatedFromCollectionCreateUserIfNotExist(string firstName, str new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)} }; - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock.Object); - var service = new MyService(userRepository); - //act - var ex = Assert.ThrowsAsync(() => - service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); - //assert - Assert.AreEqual(expectedError, ex.Message); - } + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock.Object); + var service = new MyService(userRepository); + //act + var ex = Assert.ThrowsAsync(() => + service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); + //assert + Assert.AreEqual(expectedError, ex.Message); + } - [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] - public async Task DbSetCreateUser(string firstName, string lastName, DateTime dateOfBirth) - { - //arrange - var userEntities = new List(); - var mock = userEntities.AsQueryable().BuildMockDbSet(); - - mock.Setup(set => set.AddAsync(It.IsAny(), It.IsAny())) - .Callback((UserEntity entity, CancellationToken _) => userEntities.Add(entity)); - var userRepository = new TestDbSetRepository(mock.Object); - var service = new MyService(userRepository); - //act - await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); - // assert - var entity = mock.Object.Single(); - Assert.AreEqual(firstName, entity.FirstName); - Assert.AreEqual(lastName, entity.LastName); - Assert.AreEqual(dateOfBirth, entity.DateOfBirth); - } + [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] + public async Task DbSetCreateUser(string firstName, string lastName, DateTime dateOfBirth) + { + //arrange + var userEntities = new List(); + var mock = userEntities.AsQueryable().BuildMockDbSet(); + + mock.Setup(set => set.AddAsync(It.IsAny(), It.IsAny())) + .Callback((UserEntity entity, CancellationToken _) => userEntities.Add(entity)); + var userRepository = new TestDbSetRepository(mock.Object); + var service = new MyService(userRepository); + //act + await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); + // assert + var entity = mock.Object.Single(); + Assert.AreEqual(firstName, entity.FirstName); + Assert.AreEqual(lastName, entity.LastName); + Assert.AreEqual(dateOfBirth, entity.DateOfBirth); + } - [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] - public async Task DbSetCreatedFromCollectionCreateUser(string firstName, string lastName, DateTime dateOfBirth) - { - //arrange - var userEntities = new List(); - var mock = userEntities.BuildMockDbSet(); - - mock.Setup(set => set.AddAsync(It.IsAny(), It.IsAny())) - .Callback((UserEntity entity, CancellationToken _) => userEntities.Add(entity)); - var userRepository = new TestDbSetRepository(mock.Object); - var service = new MyService(userRepository); - //act - await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); - // assert - var entity = mock.Object.Single(); - Assert.AreEqual(firstName, entity.FirstName); - Assert.AreEqual(lastName, entity.LastName); - Assert.AreEqual(dateOfBirth, entity.DateOfBirth); - } + [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] + public async Task DbSetCreatedFromCollectionCreateUser(string firstName, string lastName, DateTime dateOfBirth) + { + //arrange + var userEntities = new List(); + var mock = userEntities.BuildMockDbSet(); + + mock.Setup(set => set.AddAsync(It.IsAny(), It.IsAny())) + .Callback((UserEntity entity, CancellationToken _) => userEntities.Add(entity)); + var userRepository = new TestDbSetRepository(mock.Object); + var service = new MyService(userRepository); + //act + await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); + // assert + var entity = mock.Object.Single(); + Assert.AreEqual(firstName, entity.FirstName); + Assert.AreEqual(lastName, entity.LastName); + Assert.AreEqual(dateOfBirth, entity.DateOfBirth); + } - [TestCase("01/20/2012", "06/20/2018", 5)] - [TestCase("01/20/2012", "06/20/2012", 4)] - [TestCase("01/20/2012", "02/20/2012", 3)] - [TestCase("01/20/2010", "02/20/2011", 0)] - public async Task DbSetGetUserReports(DateTime from, DateTime to, int expectedCount) - { - //arrange - var users = CreateUserList(); - var mock = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock.Object); - var service = new MyService(userRepository); - //act - var result = await service.GetUserReports(from, to); - //assert - Assert.AreEqual(expectedCount, result.Count); - } + [TestCase("01/20/2012", "06/20/2018", 5)] + [TestCase("01/20/2012", "06/20/2012", 4)] + [TestCase("01/20/2012", "02/20/2012", 3)] + [TestCase("01/20/2010", "02/20/2011", 0)] + public async Task DbSetGetUserReports(DateTime from, DateTime to, int expectedCount) + { + //arrange + var users = CreateUserList(); + var mock = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock.Object); + var service = new MyService(userRepository); + //act + var result = await service.GetUserReports(from, to); + //assert + Assert.AreEqual(expectedCount, result.Count); + } - [TestCase("01/20/2012", "06/20/2018", 5)] - [TestCase("01/20/2012", "06/20/2012", 4)] - [TestCase("01/20/2012", "02/20/2012", 3)] - [TestCase("01/20/2010", "02/20/2011", 0)] - public async Task DbSetCreatedFromCollectionGetUserReports(DateTime from, DateTime to, int expectedCount) - { - //arrange - var users = CreateUserList(); - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock.Object); - var service = new MyService(userRepository); - //act - var result = await service.GetUserReports(from, to); - //assert - Assert.AreEqual(expectedCount, result.Count); - } + [TestCase("01/20/2012", "06/20/2018", 5)] + [TestCase("01/20/2012", "06/20/2012", 4)] + [TestCase("01/20/2012", "02/20/2012", 3)] + [TestCase("01/20/2010", "02/20/2011", 0)] + public async Task DbSetCreatedFromCollectionGetUserReports(DateTime from, DateTime to, int expectedCount) + { + //arrange + var users = CreateUserList(); + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock.Object); + var service = new MyService(userRepository); + //act + var result = await service.GetUserReports(from, to); + //assert + Assert.AreEqual(expectedCount, result.Count); + } - [Test] - public async Task DbSetGetAllUserEntity() - { - //arrange - var users = CreateUserList(); - var mock = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock.Object); - //act - var result = await userRepository.GetAll(); - //assert - Assert.AreEqual(users.Count, result.Count); - } + [Test] + public async Task DbSetGetAllUserEntity() + { + //arrange + var users = CreateUserList(); + var mock = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock.Object); + //act + var result = await userRepository.GetAll(); + //assert + Assert.AreEqual(users.Count, result.Count); + } - [Test] - public async Task DbSetCreatedFromCollectionGetAllUserEntity() - { - //arrange - var users = CreateUserList(); - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock.Object); - //act - var result = await userRepository.GetAll(); - //assert - Assert.AreEqual(users.Count, result.Count); - } + [Test] + public async Task DbSetCreatedFromCollectionGetAllUserEntity() + { + //arrange + var users = CreateUserList(); + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock.Object); + //act + var result = await userRepository.GetAll(); + //assert + Assert.AreEqual(users.Count, result.Count); + } - [Test] - public async Task DbSetFindAsyncUserEntity() - { - //arrange - var userId = Guid.NewGuid(); - var users = new List + [Test] + public async Task DbSetFindAsyncUserEntity() + { + //arrange + var userId = Guid.NewGuid(); + var users = new List { new UserEntity { @@ -270,29 +270,29 @@ public async Task DbSetFindAsyncUserEntity() } }; - var mock = users.AsQueryable().BuildMockDbSet(); - mock.Setup(x => x.FindAsync(It.IsAny())).ReturnsAsync((object[] ids) => - { - var id = (Guid) ids.First(); - return users.FirstOrDefault(x => x.Id == id); - }); - var userRepository = new TestDbSetRepository(mock.Object); + var mock = users.AsQueryable().BuildMockDbSet(); + mock.Setup(x => x.FindAsync(It.IsAny())).ReturnsAsync((object[] ids) => + { + var id = (Guid)ids.First(); + return users.FirstOrDefault(x => x.Id == id); + }); + var userRepository = new TestDbSetRepository(mock.Object); - //act - var result = await ((DbSet)userRepository.GetQueryable()).FindAsync(userId); + //act + var result = await ((DbSet)userRepository.GetQueryable()).FindAsync(userId); - //assert - Assert.IsNotNull(result); - Assert.AreEqual("FirstName3", result.FirstName); - } + //assert + Assert.IsNotNull(result); + Assert.AreEqual("FirstName3", result.FirstName); + } - [Test] - public async Task DbSetCreatedFromCollectionFindAsyncUserEntity() - { - //arrange - var userId = Guid.NewGuid(); - var users = new List + [Test] + public async Task DbSetCreatedFromCollectionFindAsyncUserEntity() + { + //arrange + var userId = Guid.NewGuid(); + var users = new List { new UserEntity { @@ -326,143 +326,170 @@ public async Task DbSetCreatedFromCollectionFindAsyncUserEntity() } }; - var mock = users.BuildMockDbSet(); - mock.Setup(x => x.FindAsync(It.IsAny())).ReturnsAsync((object[] ids) => - { - var id = (Guid)ids.First(); - return users.FirstOrDefault(x => x.Id == id); - }); - var userRepository = new TestDbSetRepository(mock.Object); + var mock = users.BuildMockDbSet(); + mock.Setup(x => x.FindAsync(It.IsAny())).ReturnsAsync((object[] ids) => + { + var id = (Guid)ids.First(); + return users.FirstOrDefault(x => x.Id == id); + }); + var userRepository = new TestDbSetRepository(mock.Object); - //act - var result = await ((DbSet)userRepository.GetQueryable()).FindAsync(userId); + //act + var result = await ((DbSet)userRepository.GetQueryable()).FindAsync(userId); - //assert - Assert.IsNotNull(result); - Assert.AreEqual("FirstName3", result.FirstName); - } + //assert + Assert.IsNotNull(result); + Assert.AreEqual("FirstName3", result.FirstName); + } - [Test] - public async Task DbSetGetAllUserEntitiesAsync() - { - // arrange - var users = CreateUserList(); + [Test] + public async Task DbSetGetAllUserEntitiesAsync() + { + // arrange + var users = CreateUserList(); - var mockDbSet = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet.Object); + var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet.Object); - // act - var result = await userRepository.GetAllAsync().ToListAsync(); + // act + var result = await userRepository.GetAllAsync().ToListAsync(); - // assert - Assert.AreEqual(users.Count, result.Count); - } + // assert + Assert.AreEqual(users.Count, result.Count); + } - [Test] - public async Task DbSetToListAsyncAsync_ShouldReturnAllEntities_WhenSourceIsChanged() - { - // arrange - var users = new List(); + [Test] + public async Task DbSetGetAllUserEntitiesAsync_ShouldReturnAllEntities_WhenSourceIsChanged() + { + // arrange + var users = new List(); - var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet.Object); - // act - var result1 = await mockDbSet.Object.ToListAsync(); - users.AddRange(CreateUserList()); - var result2 = await mockDbSet.Object.ToListAsync(); + // act + var result1 = await userRepository.GetAllAsync().ToListAsync(); + users.AddRange(CreateUserList()); + var result2 = await userRepository.GetAllAsync().ToListAsync(); - // assert - Assert.AreEqual(0, result1.Count); - Assert.AreEqual(users.Count, result2.Count); - } + // assert + Assert.AreEqual(0, result1.Count); + Assert.AreEqual(users.Count, result2.Count); + } - [Test] - public async Task DbSetCreatedFromCollectionGetAllUserEntitiesAsync() - { - // arrange - var users = CreateUserList(); + [Test] + public async Task DbSetCreatedFromCollectionGetAllUserEntitiesAsync() + { + // arrange + var users = CreateUserList(); - var mockDbSet = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet.Object); + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet.Object); - // act - var result = await userRepository.GetAllAsync().ToListAsync(); + // act + var result = await userRepository.GetAllAsync().ToListAsync(); - // assert - Assert.AreEqual(users.Count, result.Count); - } + // assert + Assert.AreEqual(users.Count, result.Count); + } - [Test] - public async Task DbSetCreatedFromCollectionExecuteDeleteAsync() - { - // arrange - var userId = Guid.NewGuid(); - var users = CreateUserList(userId); + [Test] + public async Task DbSetCreatedFromCollection_ExecuteDeleteAsync_NoInterceptionEntityNotRemoved() + { + // arrange + var userId = Guid.NewGuid(); + var users = CreateUserList(userId); - var mockDbSet = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet.Object); + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet.Object); - // act - var count = await userRepository.DeleteUserAsync(userId); + // act + var count = await userRepository.DeleteUserAsync(userId); - // assert - Assert.AreEqual(1, count); + // assert + Assert.AreEqual(1, count); + var updatedUsers = await userRepository.GetAllAsync().ToListAsync(); + Assert.IsNotNull(updatedUsers.SingleOrDefault(x => x.Id == userId)); + } - } + [Test] + public async Task DbSetCreatedFromCollection_ExecuteDeleteAsync_InterceptionEntityRemoved() + { + // arrange + var userId = Guid.NewGuid(); + var users = CreateUserList(userId); - [Test] - public async Task DbSetCreatedFromCollectionExecuteDeleteAsync_ShouldReturnZero() - { - // arrange - var userId = Guid.NewGuid(); - var users = CreateUserList(userId); + var mockDbSet = users.BuildMockDbSetWithInterceptedExecuteDelete(); + var userRepository = new TestDbSetRepository(mockDbSet.Object); - var mockDbSet = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet.Object); + // act + var count = await userRepository.DeleteUserAsync(userId); - //act - var count = await userRepository.DeleteUserAsync(Guid.NewGuid()); + // assert + Assert.AreEqual(1, count); + var updatedUsers = await userRepository.GetAllAsync().ToListAsync(); + Assert.IsNull(updatedUsers.SingleOrDefault(x => x.Id == userId)); + } - // assert - Assert.AreEqual(0, count); - } + [Test] + public async Task DbSetCreatedFromCollectionExecuteDeleteAsync_ShouldReturnZero() + { + // arrange + var userId = Guid.NewGuid(); + var users = CreateUserList(userId); - [Test] - public async Task DbSetCreatedFromCollectionExecuteUpdateAsync() - { - // arrange - var userId = Guid.NewGuid(); - var users = CreateUserList(userId); - - var mockDbSet = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet.Object); - - //act - var count = await userRepository.UpdateFirstNameByIdAsync(userId, "Unit Test"); - - //assert - Assert.AreEqual(1, count); - } + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet.Object); - [Test] - public async Task DbSetCreatedFromCollectionExecuteUpdateAsync_ShouldReturnZero() - { - // arrange - var userId = Guid.NewGuid(); - var users = CreateUserList(userId); + //act + var count = await userRepository.DeleteUserAsync(Guid.NewGuid()); - var mockDbSet = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet.Object); + // assert + Assert.AreEqual(0, count); + } - //act - var count = await userRepository.UpdateFirstNameByIdAsync(Guid.NewGuid(), "Unit Test"); + [Test] + public async Task DbSetCreatedFromCollectionExecuteUpdateAsync() + { + // arrange + var userId = Guid.NewGuid(); + var users = CreateUserList(userId); - //assert - Assert.AreEqual(0, count); - } + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet.Object); + + //act + var count = await userRepository.UpdateFirstAndLastNameByIdAsync(userId, "Unit Test"); + + //assert + Assert.AreEqual(1, count); + var user = users.Single(x => x.Id == userId); + user.FirstName = "Unit Test"; + user.LastName = "Unit Test"; + } + + [Test] + public async Task DbSetCreatedFromCollectionExecuteUpdateAsync_ShouldReturnZero() + { + // arrange + var userId = Guid.NewGuid(); + var users = CreateUserList(userId); - private static List CreateUserList(Guid? userId = null) => new List + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet.Object); + + //act + var count = await userRepository.UpdateFirstAndLastNameByIdAsync(Guid.NewGuid(), "Unit Test"); + + //assert + Assert.AreEqual(0, count); + var user = users.Single(x => x.Id == userId); + user.FirstName = "Unit Test"; + user.LastName = "Unit Test"; + } + + private static List CreateUserList(Guid? userId = null) => new List { new UserEntity { Id = userId ?? Guid.NewGuid(), FirstName = "FirstName1", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, new UserEntity { Id = Guid.NewGuid(), FirstName = "FirstName2", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, @@ -470,5 +497,5 @@ public async Task DbSetCreatedFromCollectionExecuteUpdateAsync_ShouldReturnZero( new UserEntity { Id = Guid.NewGuid(), FirstName = "FirstName3", LastName = "LastName", DateOfBirth = DateTime.Parse("03/20/2012", UsCultureInfo.DateTimeFormat) }, new UserEntity { Id = Guid.NewGuid(), FirstName = "FirstName5", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2018", UsCultureInfo.DateTimeFormat) }, }; - } + } } \ No newline at end of file diff --git a/src/MockQueryable/MockQueryable.Sample/MyServiceNSubstituteTests.cs b/src/MockQueryable/MockQueryable.Sample/MyServiceNSubstituteTests.cs index d7f75fc..c46a56b 100644 --- a/src/MockQueryable/MockQueryable.Sample/MyServiceNSubstituteTests.cs +++ b/src/MockQueryable/MockQueryable.Sample/MyServiceNSubstituteTests.cs @@ -9,103 +9,103 @@ namespace MockQueryable.Sample { - [TestFixture] - public class MyServiceNSubstituteTests + [TestFixture] + public class MyServiceNSubstituteTests + { + private static readonly CultureInfo UsCultureInfo = new CultureInfo("en-US"); + + + [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] + [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] + [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] + public void CreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) { - private static readonly CultureInfo UsCultureInfo = new CultureInfo("en-US"); - - - [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] - [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] - [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] - public void CreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) - { - //arrange - var userRepository = Substitute.For(); - var service = new MyService(userRepository); - var users = new List - { - new UserEntity{LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, - new UserEntity{FirstName = "ExistFirstName"}, - new UserEntity{DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, - new UserEntity{DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, - new UserEntity{DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, - }; - //expect - var mock = users.BuildMock(); - userRepository.GetQueryable().Returns(mock); - //act - var ex= Assert.ThrowsAsync(() => service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); - //assert - Assert.AreEqual(expectedError, ex.Message); - - } - - [TestCase("01/20/2012", "06/20/2018",5)] - [TestCase("01/20/2012", "06/20/2012",4)] - [TestCase("01/20/2012", "02/20/2012",3)] - [TestCase("01/20/2010", "02/20/2011",0)] - public async Task GetUserReports(DateTime from, DateTime to, int expectedCount) - { - //arrange - var userRepository = Substitute.For(); - var service = new MyService(userRepository); - List users = CreateUserList(); - - //expect - var mock = users.BuildMock(); - userRepository.GetQueryable().Returns(mock); - //act - var result = await service.GetUserReports(from, to); - //assert - Assert.AreEqual(expectedCount, result.Count); - } - - [TestCase("01/20/2012", "06/20/2018", 5)] - [TestCase("01/20/2012", "06/20/2012", 4)] - [TestCase("01/20/2012", "02/20/2012", 3)] - [TestCase("01/20/2010", "02/20/2011", 0)] - public async Task GetUserReports_AutoMap(DateTime from, DateTime to, int expectedCount) - { - //arrange - List users = CreateUserList(); - - var mock = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - //act - var result = await service.GetUserReportsAutoMap(from, to); - //assert - Assert.AreEqual(expectedCount, result.Count); - - } - - [TestCase("01/20/2012", "06/20/2018", 5)] - [TestCase("01/20/2012", "06/20/2012", 4)] - [TestCase("01/20/2012", "02/20/2012", 3)] - [TestCase("01/20/2010", "02/20/2011", 0)] - public async Task GetUserReports_AutoMap_FromDbSetCreatedFromCollection(DateTime from, DateTime to, int expectedCount) - { - //arrange - List users = CreateUserList(); - - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - //act - var result = await service.GetUserReportsAutoMap(from, to); - //assert - Assert.AreEqual(expectedCount, result.Count); - - } - - [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] - [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] - [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] - public void DbSetCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) - { - //arrange - var users = new List + //arrange + var userRepository = Substitute.For(); + var service = new MyService(userRepository); + var users = new List + { + new UserEntity{LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, + new UserEntity{FirstName = "ExistFirstName"}, + new UserEntity{DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, + new UserEntity{DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, + new UserEntity{DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, + }; + //expect + var mock = users.BuildMock(); + userRepository.GetQueryable().Returns(mock); + //act + var ex = Assert.ThrowsAsync(() => service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); + //assert + Assert.AreEqual(expectedError, ex.Message); + + } + + [TestCase("01/20/2012", "06/20/2018", 5)] + [TestCase("01/20/2012", "06/20/2012", 4)] + [TestCase("01/20/2012", "02/20/2012", 3)] + [TestCase("01/20/2010", "02/20/2011", 0)] + public async Task GetUserReports(DateTime from, DateTime to, int expectedCount) + { + //arrange + var userRepository = Substitute.For(); + var service = new MyService(userRepository); + List users = CreateUserList(); + + //expect + var mock = users.BuildMock(); + userRepository.GetQueryable().Returns(mock); + //act + var result = await service.GetUserReports(from, to); + //assert + Assert.AreEqual(expectedCount, result.Count); + } + + [TestCase("01/20/2012", "06/20/2018", 5)] + [TestCase("01/20/2012", "06/20/2012", 4)] + [TestCase("01/20/2012", "02/20/2012", 3)] + [TestCase("01/20/2010", "02/20/2011", 0)] + public async Task GetUserReports_AutoMap(DateTime from, DateTime to, int expectedCount) + { + //arrange + List users = CreateUserList(); + + var mock = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + //act + var result = await service.GetUserReportsAutoMap(from, to); + //assert + Assert.AreEqual(expectedCount, result.Count); + + } + + [TestCase("01/20/2012", "06/20/2018", 5)] + [TestCase("01/20/2012", "06/20/2012", 4)] + [TestCase("01/20/2012", "02/20/2012", 3)] + [TestCase("01/20/2010", "02/20/2011", 0)] + public async Task GetUserReports_AutoMap_FromDbSetCreatedFromCollection(DateTime from, DateTime to, int expectedCount) + { + //arrange + List users = CreateUserList(); + + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + //act + var result = await service.GetUserReportsAutoMap(from, to); + //assert + Assert.AreEqual(expectedCount, result.Count); + + } + + [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] + [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] + [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] + public void DbSetCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) + { + //arrange + var users = new List { new UserEntity{LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, new UserEntity{FirstName = "ExistFirstName"}, @@ -113,24 +113,24 @@ public void DbSetCreateUserIfNotExist(string firstName, string lastName, DateTim new UserEntity{DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, new UserEntity{DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, }; - var mock = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - //act - var ex = Assert.ThrowsAsync(() => service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); - //assert - Assert.AreEqual(expectedError, ex.Message); + var mock = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + //act + var ex = Assert.ThrowsAsync(() => service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); + //assert + Assert.AreEqual(expectedError, ex.Message); - } + } - [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] - [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] - [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] - public void DbSetCreatedFromCollectionCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) - { - //arrange - var users = new List + [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] + [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] + [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] + public void DbSetCreatedFromCollectionCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) + { + //arrange + var users = new List { new UserEntity{LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, new UserEntity{FirstName = "ExistFirstName"}, @@ -138,277 +138,301 @@ public void DbSetCreatedFromCollectionCreateUserIfNotExist(string firstName, str new UserEntity{DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, new UserEntity{DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, }; - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - //act - var ex = Assert.ThrowsAsync(() => service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); - //assert - Assert.AreEqual(expectedError, ex.Message); - - } - - [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] - public async Task DbSetCreateUser(string firstName, string lastName, DateTime dateOfBirth) - { - //arrange - var userEntities = new List(); - var mock = userEntities.AsQueryable().BuildMockDbSet(); - mock.AddAsync(Arg.Any()) - .Returns(info => null) - .AndDoes(info => userEntities.Add(info.Arg())); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - //act - await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); - // assert - var entity = mock.Single(); - Assert.AreEqual(firstName, entity.FirstName); - Assert.AreEqual(lastName, entity.LastName); - Assert.AreEqual(dateOfBirth, entity.DateOfBirth); - } - - [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] - public async Task DbSetCreatedFromCollectionCreateUser(string firstName, string lastName, DateTime dateOfBirth) - { - //arrange - var userEntities = new List(); - var mock = userEntities.BuildMockDbSet(); - mock.AddAsync(Arg.Any()) - .Returns(info => null) - .AndDoes(info => userEntities.Add(info.Arg())); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - //act - await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); - // assert - var entity = mock.Single(); - Assert.AreEqual(firstName, entity.FirstName); - Assert.AreEqual(lastName, entity.LastName); - Assert.AreEqual(dateOfBirth, entity.DateOfBirth); - } - - [TestCase("01/20/2012", "06/20/2018", 5)] - [TestCase("01/20/2012", "06/20/2012", 4)] - [TestCase("01/20/2012", "02/20/2012", 3)] - [TestCase("01/20/2010", "02/20/2011", 0)] - public async Task DbSetGetUserReports(DateTime from, DateTime to, int expectedCount) - { - //arrange - var users = CreateUserList(); - - var mock = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - //act - var result = await service.GetUserReports(from, to); - //assert - Assert.AreEqual(expectedCount, result.Count); - } - - [TestCase("01/20/2012", "06/20/2018", 5)] - [TestCase("01/20/2012", "06/20/2012", 4)] - [TestCase("01/20/2012", "02/20/2012", 3)] - [TestCase("01/20/2010", "02/20/2011", 0)] - public async Task DbSetCreatedFromCollectionGetUserReports(DateTime from, DateTime to, int expectedCount) - { - //arrange - var users = CreateUserList(); - - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - //act - var result = await service.GetUserReports(from, to); - //assert - Assert.AreEqual(expectedCount, result.Count); - } - - [Test] - public async Task DbSetGetAllUserEntity() - { - //arrange - var users = CreateUserList(); - var mock = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - //act - var result = await userRepository.GetAll(); - //assert - Assert.AreEqual(users.Count, result.Count); - } - - [Test] - public async Task DbSetCreatedFromCollectionGetAllUserEntity() - { - //arrange - var users = CreateUserList(); - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - //act - var result = await userRepository.GetAll(); - //assert - Assert.AreEqual(users.Count, result.Count); - } - - [Test] - public async Task DbSetGetAllUserEntitiesAsync() - { - // arrange - var users = CreateUserList(); - - var mockDbSet = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet); - - // act - var result = await userRepository.GetAllAsync().ToListAsync(); - - // assert - Assert.AreEqual(users.Count, result.Count); - } - - - [Test] - public async Task DbSetGetAllUserEntitiesAsync_ShouldReturnAllEntities_WhenSourceIsChanged() - { - // arrange - var users = new List(); + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + //act + var ex = Assert.ThrowsAsync(() => service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); + //assert + Assert.AreEqual(expectedError, ex.Message); - var mockDbSet = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet); + } - // act - var result1 = await userRepository.GetAllAsync().ToListAsync(); - users.AddRange(CreateUserList()); - var result2 = await userRepository.GetAllAsync().ToListAsync(); + [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] + public async Task DbSetCreateUser(string firstName, string lastName, DateTime dateOfBirth) + { + //arrange + var userEntities = new List(); + var mock = userEntities.AsQueryable().BuildMockDbSet(); + mock.AddAsync(Arg.Any()) + .Returns(info => null) + .AndDoes(info => userEntities.Add(info.Arg())); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + //act + await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); + // assert + var entity = mock.Single(); + Assert.AreEqual(firstName, entity.FirstName); + Assert.AreEqual(lastName, entity.LastName); + Assert.AreEqual(dateOfBirth, entity.DateOfBirth); + } - // assert - Assert.AreEqual(0, result1.Count); - Assert.AreEqual(users.Count, result2.Count); - } + [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] + public async Task DbSetCreatedFromCollectionCreateUser(string firstName, string lastName, DateTime dateOfBirth) + { + //arrange + var userEntities = new List(); + var mock = userEntities.BuildMockDbSet(); + mock.AddAsync(Arg.Any()) + .Returns(info => null) + .AndDoes(info => userEntities.Add(info.Arg())); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + //act + await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); + // assert + var entity = mock.Single(); + Assert.AreEqual(firstName, entity.FirstName); + Assert.AreEqual(lastName, entity.LastName); + Assert.AreEqual(dateOfBirth, entity.DateOfBirth); + } - [Test] - public async Task DbSetCreatedFromCollectionGetAllUserEntitiesAsync() - { - // arrange - var users = CreateUserList(); + [TestCase("01/20/2012", "06/20/2018", 5)] + [TestCase("01/20/2012", "06/20/2012", 4)] + [TestCase("01/20/2012", "02/20/2012", 3)] + [TestCase("01/20/2010", "02/20/2011", 0)] + public async Task DbSetGetUserReports(DateTime from, DateTime to, int expectedCount) + { + //arrange + var users = CreateUserList(); + + var mock = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + //act + var result = await service.GetUserReports(from, to); + //assert + Assert.AreEqual(expectedCount, result.Count); + } + + [TestCase("01/20/2012", "06/20/2018", 5)] + [TestCase("01/20/2012", "06/20/2012", 4)] + [TestCase("01/20/2012", "02/20/2012", 3)] + [TestCase("01/20/2010", "02/20/2011", 0)] + public async Task DbSetCreatedFromCollectionGetUserReports(DateTime from, DateTime to, int expectedCount) + { + //arrange + var users = CreateUserList(); + + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + //act + var result = await service.GetUserReports(from, to); + //assert + Assert.AreEqual(expectedCount, result.Count); + } + + [Test] + public async Task DbSetGetAllUserEntity() + { + //arrange + var users = CreateUserList(); + var mock = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + //act + var result = await userRepository.GetAll(); + //assert + Assert.AreEqual(users.Count, result.Count); + } - var mockDbSet = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet); + [Test] + public async Task DbSetCreatedFromCollectionGetAllUserEntity() + { + //arrange + var users = CreateUserList(); + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + //act + var result = await userRepository.GetAll(); + //assert + Assert.AreEqual(users.Count, result.Count); + } - // act - var result = await userRepository.GetAllAsync().ToListAsync(); + [Test] + public async Task DbSetGetAllUserEntitiesAsync() + { + // arrange + var users = CreateUserList(); - // assert - Assert.AreEqual(users.Count, result.Count); - } + var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); - [Test] - public async Task DbSetGetOneUserTntityAsync() - { - // arrange - var users = CreateUserList(); + // act + var result = await userRepository.GetAllAsync().ToListAsync(); - var mockDbSet = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet); + // assert + Assert.AreEqual(users.Count, result.Count); + } - // act - var result = await userRepository.GetAllAsync() - .Where(user => user.FirstName == "FirstName1") - .FirstOrDefaultAsync(); + [Test] + public async Task DbSetGetAllUserEntitiesAsync_ShouldReturnAllEntities_WhenSourceIsChanged() + { + // arrange + var users = new List(); - // assert - Assert.AreEqual(users.First(), result); - } + var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); - [Test] - public async Task DbSetCreatedFromCollectionGetOneUserTntityAsync() - { - // arrange - var users = CreateUserList(); + // act + var result1 = await userRepository.GetAllAsync().ToListAsync(); + users.AddRange(CreateUserList()); + var result2 = await userRepository.GetAllAsync().ToListAsync(); - var mockDbSet = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet); + // assert + Assert.AreEqual(0, result1.Count); + Assert.AreEqual(users.Count, result2.Count); + } - // act - var result = await userRepository.GetAllAsync() - .Where(user => user.FirstName == "FirstName1") - .FirstOrDefaultAsync(); + [Test] + public async Task DbSetCreatedFromCollectionGetAllUserEntitiesAsync() + { + // arrange + var users = CreateUserList(); - // assert - Assert.AreEqual(users.First(), result); - } + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); + // act + var result = await userRepository.GetAllAsync().ToListAsync(); - [Test] - public async Task DbSetCreatedFromCollectionExecuteDeleteAsync() - { - // arrange - var userId = Guid.NewGuid(); - var users = CreateUserList(userId); + // assert + Assert.AreEqual(users.Count, result.Count); + } - var mockDbSet = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet); + [Test] + public async Task DbSetGetOneUserTntityAsync() + { + // arrange + var users = CreateUserList(); - // act - var count = await userRepository.DeleteUserAsync(userId); + var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); - // assert - Assert.AreEqual(1, count); + // act + var result = await userRepository.GetAllAsync() + .Where(user => user.FirstName == "FirstName1") + .FirstOrDefaultAsync(); - } + // assert + Assert.AreEqual(users.First(), result); + } - [Test] - public async Task DbSetCreatedFromCollectionExecuteDeleteAsync_ShouldReturnZero() - { - // arrange - var userId = Guid.NewGuid(); - var users = CreateUserList(userId); + [Test] + public async Task DbSetCreatedFromCollectionGetOneUserTntityAsync() + { + // arrange + var users = CreateUserList(); - var mockDbSet = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet); + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); - //act - var count = await userRepository.DeleteUserAsync(Guid.NewGuid()); + // act + var result = await userRepository.GetAllAsync() + .Where(user => user.FirstName == "FirstName1") + .FirstOrDefaultAsync(); - // assert - Assert.AreEqual(0, count); - } + // assert + Assert.AreEqual(users.First(), result); + } - [Test] - public async Task DbSetCreatedFromCollectionExecuteUpdateAsync() - { - // arrange - var userId = Guid.NewGuid(); - var users = CreateUserList(userId); - - var mockDbSet = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet); - - //act - var count = await userRepository.UpdateFirstNameByIdAsync(userId, "Unit Test"); - - //assert - Assert.AreEqual(1, count); - } - - [Test] - public async Task DbSetCreatedFromCollectionExecuteUpdateAsync_ShouldReturnZero() - { - // arrange - var userId = Guid.NewGuid(); - var users = CreateUserList(userId); + [Test] + public async Task DbSetCreatedFromCollection_ExecuteDeleteAsync_NoInterceptionEntityNotRemoved() + { + // arrange + var userId = Guid.NewGuid(); + var users = CreateUserList(userId); + + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); + + // act + var count = await userRepository.DeleteUserAsync(userId); + + // assert + Assert.AreEqual(1, count); + var updatedUsers = await userRepository.GetAllAsync().ToListAsync(); + Assert.IsNotNull(updatedUsers.SingleOrDefault(x => x.Id == userId)); + } + + [Test] + public async Task DbSetCreatedFromCollection_ExecuteDeleteAsync_InterceptionEntityRemoved() + { + // arrange + var userId = Guid.NewGuid(); + var users = CreateUserList(userId); + + var mockDbSet = users.BuildMockDbSetWithInterceptedExecuteDelete(); + var userRepository = new TestDbSetRepository(mockDbSet); + + // act + var count = await userRepository.DeleteUserAsync(userId); + + // assert + Assert.AreEqual(1, count); + var updatedUsers = await userRepository.GetAllAsync().ToListAsync(); + Assert.IsNull(updatedUsers.SingleOrDefault(x => x.Id == userId)); + } + + [Test] + public async Task DbSetCreatedFromCollectionExecuteDeleteAsync_ShouldReturnZero() + { + // arrange + var userId = Guid.NewGuid(); + var users = CreateUserList(userId); - var mockDbSet = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet); + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); - //act - var count = await userRepository.UpdateFirstNameByIdAsync(Guid.NewGuid(), "Unit Test"); + //act + var count = await userRepository.DeleteUserAsync(Guid.NewGuid()); - //assert - Assert.AreEqual(0, count); - } + // assert + Assert.AreEqual(0, count); + } + + [Test] + public async Task DbSetCreatedFromCollectionExecuteUpdateAsync() + { + // arrange + var userId = Guid.NewGuid(); + var users = CreateUserList(userId); - private static List CreateUserList(Guid? userId = null) => new List + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); + + //act + var count = await userRepository.UpdateFirstAndLastNameByIdAsync(userId, "Unit Test"); + + //assert + Assert.AreEqual(1, count); + var user = users.Single(x => x.Id == userId); + user.FirstName = "Unit Test"; + user.LastName = "Unit Test"; + } + + [Test] + public async Task DbSetCreatedFromCollectionExecuteUpdateAsync_ShouldReturnZero() + { + // arrange + var userId = Guid.NewGuid(); + var users = CreateUserList(userId); + + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); + + //act + var count = await userRepository.UpdateFirstAndLastNameByIdAsync(Guid.NewGuid(), "Unit Test"); + + //assert + Assert.AreEqual(0, count); + var user = users.Single(x => x.Id == userId); + user.FirstName = "Unit Test"; + user.LastName = "Unit Test"; + } + + private static List CreateUserList(Guid? userId = null) => new List { new UserEntity { Id = userId ?? Guid.NewGuid(), FirstName = "FirstName1", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, new UserEntity { Id = Guid.NewGuid(), FirstName = "FirstName2", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, @@ -417,5 +441,5 @@ public async Task DbSetCreatedFromCollectionExecuteUpdateAsync_ShouldReturnZero( new UserEntity { Id = Guid.NewGuid(), FirstName = "FirstName5", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2018", UsCultureInfo.DateTimeFormat) }, }; - } + } } diff --git a/src/MockQueryable/MockQueryable.Sample/TestDbSetRepository.cs b/src/MockQueryable/MockQueryable.Sample/TestDbSetRepository.cs index b1f8fec..18d03c2 100644 --- a/src/MockQueryable/MockQueryable.Sample/TestDbSetRepository.cs +++ b/src/MockQueryable/MockQueryable.Sample/TestDbSetRepository.cs @@ -6,43 +6,44 @@ namespace MockQueryable.Sample { - public class TestDbSetRepository : IUserRepository - { - private readonly DbSet _dbSet; + public class TestDbSetRepository : IUserRepository + { + private readonly DbSet _dbSet; - public TestDbSetRepository(DbSet dbSet) - { - _dbSet = dbSet; - } - public IQueryable GetQueryable() - { - return _dbSet; - } + public TestDbSetRepository(DbSet dbSet) + { + _dbSet = dbSet; + } + public IQueryable GetQueryable() + { + return _dbSet; + } - public async Task CreateUser(UserEntity user) - { - await _dbSet.AddAsync(user); - } + public async Task CreateUser(UserEntity user) + { + await _dbSet.AddAsync(user); + } - public async Task> GetAll() { - return await _dbSet.ToListAsync(); - } + public async Task> GetAll() + { + return await _dbSet.ToListAsync(); + } - public IAsyncEnumerable GetAllAsync() - { - return _dbSet.AsAsyncEnumerable(); - } + public IAsyncEnumerable GetAllAsync() + { + return _dbSet.AsAsyncEnumerable(); + } - public async Task DeleteUserAsync(Guid id) - { - return await _dbSet.Where(x => x.Id == id) - .ExecuteDeleteAsync(); - } + public async Task DeleteUserAsync(Guid id) + { + return await _dbSet.Where(x => x.Id == id) + .ExecuteDeleteAsync(); + } - public async Task UpdateFirstNameByIdAsync(Guid id, string firstName) - { - return await _dbSet.Where(x => x.Id == id) - .ExecuteUpdateAsync(opt => opt.SetProperty(x => x.FirstName, firstName)); - } + public async Task UpdateFirstAndLastNameByIdAsync(Guid id, string firstName) + { + return await _dbSet.Where(x => x.Id == id) + .ExecuteUpdateAsync(opt => opt.SetProperty(x => x.FirstName, firstName).SetProperty(x => x.LastName, firstName)); } + } } \ No newline at end of file From a89730c371d627ac868f53abb816eb97d6160843 Mon Sep 17 00:00:00 2001 From: Raman Tsitou Date: Sat, 26 Jul 2025 22:40:07 +0200 Subject: [PATCH 7/8] Corrected SampleLikeExpressionVisitor to support Like and ILike. Added additional tests for Like. Updated README --- .github/workflows/dotnetcore.yml | 2 +- README.md | 16 + .../MockQueryable.Core.csproj | 2 +- .../MockQueryable.Core/TestQueryProvider.cs | 124 ++-- .../FakeItEasyExtensions.cs | 7 +- .../MockQueryable.Moq/MoqExtensions.cs | 7 +- .../NSubstituteExtensions.cs | 7 +- .../MockQueryable.Sample.csproj | 4 + .../MyServiceFakeItEasyTests.cs | 505 +++++++++------- .../MockQueryable.Sample/MyServiceMoqTests.cs | 570 ++++++++++-------- .../MyServiceNSubstituteTests.cs | 550 ++++++++++------- .../SampleILikeExpressionVisitor .cs | 40 -- .../SampleLikeExpressionVisitor.cs | 42 ++ .../TestDbSetRepository.cs | 9 +- src/MockQueryable/MockQueryable.sln | 11 +- 15 files changed, 1068 insertions(+), 828 deletions(-) delete mode 100644 src/MockQueryable/MockQueryable.Sample/SampleILikeExpressionVisitor .cs create mode 100644 src/MockQueryable/MockQueryable.Sample/SampleLikeExpressionVisitor.cs diff --git a/.github/workflows/dotnetcore.yml b/.github/workflows/dotnetcore.yml index bd49b40..fceb363 100644 --- a/.github/workflows/dotnetcore.yml +++ b/.github/workflows/dotnetcore.yml @@ -12,7 +12,7 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v1 with: - dotnet-version: '6.0.x' + dotnet-version: '8.0.x' - name: Build with dotnet run: dotnet build src/MockQueryable/*.sln --configuration Release diff --git a/README.md b/README.md index 490c408..cc8a277 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,22 @@ var userRepository = new TestDbSetRepository(mock.Object); var user = await ((DbSet) userRepository.GetQueryable()).FindAsync(userId); ``` +You can also add your custom expression visitor with custom logic: + +```C# + +var users = new List +{ + new UserEntity{Id = userId,LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012")}, + //etc. +}; + +//Bould mock with custom SampleLikeExpressionVisitor, that emulates EF.Functions.Like +var mockDbSet = users.AsQueryable().BuildMockDbSet(); +var userRepository = new TestDbSetRepository(mockDbSet.Object); + +``` + Check out the [sample project](https://github.com/romantitov/MockQueryable/tree/master/src/MockQueryable/MockQueryable.Sample) ### Where can I get it? diff --git a/src/MockQueryable/MockQueryable.Core/MockQueryable.Core.csproj b/src/MockQueryable/MockQueryable.Core/MockQueryable.Core.csproj index 55b5ba7..a469c0c 100644 --- a/src/MockQueryable/MockQueryable.Core/MockQueryable.Core.csproj +++ b/src/MockQueryable/MockQueryable.Core/MockQueryable.Core.csproj @@ -1,7 +1,7 @@  - netstandard2.1 + net8 MockQueryable.Core Roman Titov diff --git a/src/MockQueryable/MockQueryable.Core/TestQueryProvider.cs b/src/MockQueryable/MockQueryable.Core/TestQueryProvider.cs index 92a5a95..f4b855e 100644 --- a/src/MockQueryable/MockQueryable.Core/TestQueryProvider.cs +++ b/src/MockQueryable/MockQueryable.Core/TestQueryProvider.cs @@ -6,79 +6,81 @@ namespace MockQueryable.Core { - public abstract class TestQueryProvider : IOrderedQueryable, IQueryProvider - where TExpressionVisitor : ExpressionVisitor, new() - { - private IEnumerable _enumerable; + public abstract class TestQueryProvider : IOrderedQueryable, IQueryProvider + where TExpressionVisitor : ExpressionVisitor, new() + { + private IEnumerable _enumerable; - protected TestQueryProvider(Expression expression) - { - Expression = expression; - } + protected TestQueryProvider(Expression expression) + { + Expression = expression; + } - protected TestQueryProvider(IEnumerable enumerable) - { - _enumerable = enumerable; - Expression = enumerable.AsQueryable().Expression; - } + protected TestQueryProvider(IEnumerable enumerable) + { + _enumerable = enumerable; + Expression = enumerable.AsQueryable().Expression; + } - public IQueryable CreateQuery(Expression expression) - { - if (expression is MethodCallExpression m) - { - var resultType = m.Method.ReturnType; // it should be IQueryable - var tElement = resultType.GetGenericArguments().First(); - return (IQueryable) CreateInstance(tElement, expression); - } + public IQueryable CreateQuery(Expression expression) + { + if (expression is MethodCallExpression m) + { + var resultType = m.Method.ReturnType; // it should be IQueryable + var tElement = resultType.GetGenericArguments().First(); + return (IQueryable)CreateInstance(tElement, expression); + } - return CreateQuery(expression); - } + return CreateQuery(expression); + } - public IQueryable CreateQuery(Expression expression) - { - return (IQueryable) CreateInstance(typeof(TEntity), expression); - } + public IQueryable CreateQuery(Expression expression) + { + return (IQueryable)CreateInstance(typeof(TEntity), expression); + } - private object CreateInstance(Type tElement, Expression expression) - { - var queryType = GetType().GetGenericTypeDefinition().MakeGenericType(tElement, typeof(TExpressionVisitor)); - return Activator.CreateInstance(queryType, expression); - } + private object CreateInstance(Type tElement, Expression expression) + { + var queryType = GetType().GetGenericTypeDefinition().MakeGenericType(tElement, typeof(TExpressionVisitor)); + return Activator.CreateInstance(queryType, expression); + } - public object Execute(Expression expression) - { - return CompileExpressionItem(expression); - } + public object Execute(Expression expression) + { + return CompileExpressionItem(expression); + } - public TResult Execute(Expression expression) - { - return CompileExpressionItem(expression); - } + public TResult Execute(Expression expression) + { + return CompileExpressionItem(expression); + } - IEnumerator IEnumerable.GetEnumerator() - { - if (_enumerable == null) _enumerable = CompileExpressionItem>(Expression); - return _enumerable.GetEnumerator(); - } + IEnumerator IEnumerable.GetEnumerator() + { + if (_enumerable == null) _enumerable = CompileExpressionItem>(Expression); + return _enumerable.GetEnumerator(); + } - IEnumerator IEnumerable.GetEnumerator() - { - if (_enumerable == null) _enumerable = CompileExpressionItem>(Expression); - return _enumerable.GetEnumerator(); - } + IEnumerator IEnumerable.GetEnumerator() + { + if (_enumerable == null) _enumerable = CompileExpressionItem>(Expression); + return _enumerable.GetEnumerator(); + } - public Type ElementType => typeof(T); + public Type ElementType => typeof(T); - public Expression Expression { get; } + public Expression Expression { get; } - public IQueryProvider Provider => this; + public IQueryProvider Provider => this; - private static TResult CompileExpressionItem(Expression expression) - { - var visitor = new TExpressionVisitor(); - var body = visitor.Visit(expression); - var f = Expression.Lambda>(body ?? throw new InvalidOperationException($"{nameof(body)} is null"), (IEnumerable) null); - return f.Compile()(); - } - } + private static TResult CompileExpressionItem(Expression expression) + { + var visitor = new TExpressionVisitor(); + var body = visitor.Visit(expression); + var f = Expression.Lambda>( + body ?? throw new InvalidOperationException($"{nameof(body)} is null"), + (IEnumerable)null); + return f.Compile()(); + } + } } \ No newline at end of file diff --git a/src/MockQueryable/MockQueryable.FakeItEasy/FakeItEasyExtensions.cs b/src/MockQueryable/MockQueryable.FakeItEasy/FakeItEasyExtensions.cs index 2fd7c40..6d7e323 100644 --- a/src/MockQueryable/MockQueryable.FakeItEasy/FakeItEasyExtensions.cs +++ b/src/MockQueryable/MockQueryable.FakeItEasy/FakeItEasyExtensions.cs @@ -38,7 +38,12 @@ public static DbSet BuildMockDbSet(this IQueryable da } /// - /// See . + /// This method allows you to create a mock DbSet for testing purposes. + /// It is particularly useful when you want to simulate the behavior of Entity Framework Core's DbSet + /// with custom expression handling, such as for testing LINQ queries or database operations. + /// The method takes an IQueryable of the entity type and returns a mocked DbSet that implements + /// both IAsyncEnumerable and IQueryable interfaces, allowing for asynchronous enumeration + /// and LINQ query capabilities. /// /// /// The type of the entity that the DbSet will represent. diff --git a/src/MockQueryable/MockQueryable.Moq/MoqExtensions.cs b/src/MockQueryable/MockQueryable.Moq/MoqExtensions.cs index c169f3b..c41118a 100644 --- a/src/MockQueryable/MockQueryable.Moq/MoqExtensions.cs +++ b/src/MockQueryable/MockQueryable.Moq/MoqExtensions.cs @@ -39,7 +39,12 @@ public static Mock> BuildMockDbSet(this IQueryable - /// See . + /// This method allows you to create a mock DbSet for testing purposes. + /// It is particularly useful when you want to simulate the behavior of Entity Framework Core's DbSet + /// with custom expression handling, such as for testing LINQ queries or database operations. + /// The method takes an IQueryable of the entity type and returns a mocked DbSet that implements + /// both IAsyncEnumerable and IQueryable interfaces, allowing for asynchronous enumeration + /// and LINQ query capabilities. /// /// /// The type of the entity that the DbSet will represent. diff --git a/src/MockQueryable/MockQueryable.NSubstitute/NSubstituteExtensions.cs b/src/MockQueryable/MockQueryable.NSubstitute/NSubstituteExtensions.cs index 1a2e25e..de28471 100644 --- a/src/MockQueryable/MockQueryable.NSubstitute/NSubstituteExtensions.cs +++ b/src/MockQueryable/MockQueryable.NSubstitute/NSubstituteExtensions.cs @@ -36,7 +36,12 @@ public static DbSet BuildMockDbSet(this IQueryable da } /// - /// See . + /// This method allows you to create a mock DbSet for testing purposes. + /// It is particularly useful when you want to simulate the behavior of Entity Framework Core's DbSet + /// with custom expression handling, such as for testing LINQ queries or database operations. + /// The method takes an IQueryable of the entity type and returns a mocked DbSet that implements + /// both IAsyncEnumerable and IQueryable interfaces, allowing for asynchronous enumeration + /// and LINQ query capabilities. /// /// /// The type of the entity that the DbSet will represent. diff --git a/src/MockQueryable/MockQueryable.Sample/MockQueryable.Sample.csproj b/src/MockQueryable/MockQueryable.Sample/MockQueryable.Sample.csproj index 60dbdf8..8402916 100644 --- a/src/MockQueryable/MockQueryable.Sample/MockQueryable.Sample.csproj +++ b/src/MockQueryable/MockQueryable.Sample/MockQueryable.Sample.csproj @@ -4,6 +4,10 @@ net8 + + + + diff --git a/src/MockQueryable/MockQueryable.Sample/MyServiceFakeItEasyTests.cs b/src/MockQueryable/MockQueryable.Sample/MyServiceFakeItEasyTests.cs index 039b6ad..52b97d3 100644 --- a/src/MockQueryable/MockQueryable.Sample/MyServiceFakeItEasyTests.cs +++ b/src/MockQueryable/MockQueryable.Sample/MyServiceFakeItEasyTests.cs @@ -9,11 +9,11 @@ using MockQueryable.FakeItEasy; using NUnit.Framework; -namespace MockQueryable.Sample +namespace MockQueryable.Sample; + +[TestFixture] +public class MyServiceFakeItEasyTests { - [TestFixture] - public class MyServiceFakeItEasyTests - { private static readonly CultureInfo UsCultureInfo = new("en-US"); [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] @@ -21,28 +21,28 @@ public class MyServiceFakeItEasyTests [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] public void CreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) { - // arrange - var userRepository = A.Fake(); - var service = new MyService(userRepository); - var users = new List - { - new() {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, - new() {FirstName = "ExistFirstName"}, - new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, - new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, - new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, - }; - - // expect - var mock = users.BuildMock(); - A.CallTo(() => userRepository.GetQueryable()).Returns(mock); - - // act - var ex = Assert.ThrowsAsync(() => - service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); - - // assert - Assert.That(expectedError, Is.EqualTo(ex.Message)); + // arrange + var userRepository = A.Fake(); + var service = new MyService(userRepository); + var users = new List + { + new() {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {FirstName = "ExistFirstName"}, + new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + }; + + // expect + var mock = users.BuildMock(); + A.CallTo(() => userRepository.GetQueryable()).Returns(mock); + + // act + var ex = Assert.ThrowsAsync(() => + service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); + + // assert + Assert.That(expectedError, Is.EqualTo(ex.Message)); } [TestCase("01/20/2012", "06/20/2018", 5)] @@ -51,17 +51,17 @@ public void CreateUserIfNotExist(string firstName, string lastName, DateTime dat [TestCase("01/20/2010", "02/20/2011", 0)] public async Task GetUserReports(DateTime from, DateTime to, int expectedCount) { - //arrange - var userRepository = A.Fake(); - var service = new MyService(userRepository); - var users = CreateUserList(); - //expect - var mock = users.BuildMock(); - A.CallTo(() => userRepository.GetQueryable()).Returns(mock); - //act - var result = await service.GetUserReports(from, to); - //assert - Assert.That(expectedCount, Is.EqualTo(result.Count)); + //arrange + var userRepository = A.Fake(); + var service = new MyService(userRepository); + var users = CreateUserList(); + //expect + var mock = users.BuildMock(); + A.CallTo(() => userRepository.GetQueryable()).Returns(mock); + //act + var result = await service.GetUserReports(from, to); + //assert + Assert.That(expectedCount, Is.EqualTo(result.Count)); } [TestCase("01/20/2012", "06/20/2018", 5)] @@ -70,19 +70,19 @@ public async Task GetUserReports(DateTime from, DateTime to, int expectedCount) [TestCase("01/20/2010", "02/20/2011", 0)] public async Task GetUserReports_AutoMap(DateTime from, DateTime to, int expectedCount) { - // arrange - var userRepository = A.Fake(); - var service = new MyService(userRepository); - var users = CreateUserList(); - // expect - var mock = users.BuildMock(); - A.CallTo(() => userRepository.GetQueryable()).Returns(mock); - - // act - var result = await service.GetUserReportsAutoMap(from, to); - - // assert - Assert.That(expectedCount, Is.EqualTo(result.Count)); + // arrange + var userRepository = A.Fake(); + var service = new MyService(userRepository); + var users = CreateUserList(); + // expect + var mock = users.BuildMock(); + A.CallTo(() => userRepository.GetQueryable()).Returns(mock); + + // act + var result = await service.GetUserReportsAutoMap(from, to); + + // assert + Assert.That(expectedCount, Is.EqualTo(result.Count)); } [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] @@ -90,25 +90,25 @@ public async Task GetUserReports_AutoMap(DateTime from, DateTime to, int expecte [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] public void DbSetCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) { - // arrange - var users = new List - { - new() {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, - new() {FirstName = "ExistFirstName"}, - new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, - new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, - new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, - }; - var mock = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - - // act - var ex = Assert.ThrowsAsync(() => - service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); - - // assert - Assert.That(expectedError, Is.EqualTo(ex.Message)); + // arrange + var users = new List + { + new() {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {FirstName = "ExistFirstName"}, + new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + }; + var mock = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + + // act + var ex = Assert.ThrowsAsync(() => + service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); + + // assert + Assert.That(expectedError, Is.EqualTo(ex.Message)); } [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] @@ -116,8 +116,8 @@ public void DbSetCreateUserIfNotExist(string firstName, string lastName, DateTim [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] public void DbSetCreatedFromCollectionCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) { - // arrange - var users = new List + // arrange + var users = new List { new() {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, new() {FirstName = "ExistFirstName"}, @@ -125,64 +125,64 @@ public void DbSetCreatedFromCollectionCreateUserIfNotExist(string firstName, str new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, }; - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - // act - var ex = Assert.ThrowsAsync(() => - service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); - // assert - Assert.That(expectedError, Is.EqualTo(ex.Message)); + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + // act + var ex = Assert.ThrowsAsync(() => + service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); + // assert + Assert.That(expectedError, Is.EqualTo(ex.Message)); } [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] public async Task DbSetCreateUser(string firstName, string lastName, DateTime dateOfBirth) { - // arrange - var userEntities = new List(); - var mock = userEntities.AsQueryable().BuildMockDbSet(); - A.CallTo(() => mock.AddAsync(A._, A._)) - .ReturnsLazily(call => - { - userEntities.Add((UserEntity)call.Arguments[0]); - return default; - }); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - - // act - await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); - - // assert - var entity = mock.Single(); - Assert.That(firstName, Is.EqualTo(entity.FirstName)); - Assert.That(lastName, Is.EqualTo(entity.LastName)); - Assert.That(dateOfBirth, Is.EqualTo(entity.DateOfBirth)); + // arrange + var userEntities = new List(); + var mock = userEntities.AsQueryable().BuildMockDbSet(); + A.CallTo(() => mock.AddAsync(A._, A._)) + .ReturnsLazily(call => + { + userEntities.Add((UserEntity)call.Arguments[0]); + return default; + }); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + + // act + await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); + + // assert + var entity = mock.Single(); + Assert.That(firstName, Is.EqualTo(entity.FirstName)); + Assert.That(lastName, Is.EqualTo(entity.LastName)); + Assert.That(dateOfBirth, Is.EqualTo(entity.DateOfBirth)); } [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] public async Task DbSetCreatedFromCollectionCreateUser1(string firstName, string lastName, DateTime dateOfBirth) { - // arrange - var userEntities = new List(); - var mock = userEntities.BuildMockDbSet(); - A.CallTo(() => mock.AddAsync(A._, A._)) - .ReturnsLazily(call => - { - userEntities.Add((UserEntity)call.Arguments[0]); - return default; - }); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - - // act - await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); - - // assert - var entity = mock.Single(); - Assert.That(firstName, Is.EqualTo(entity.FirstName)); - Assert.That(lastName, Is.EqualTo(entity.LastName)); - Assert.That(dateOfBirth, Is.EqualTo(entity.DateOfBirth)); + // arrange + var userEntities = new List(); + var mock = userEntities.BuildMockDbSet(); + A.CallTo(() => mock.AddAsync(A._, A._)) + .ReturnsLazily(call => + { + userEntities.Add((UserEntity)call.Arguments[0]); + return default; + }); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + + // act + await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); + + // assert + var entity = mock.Single(); + Assert.That(firstName, Is.EqualTo(entity.FirstName)); + Assert.That(lastName, Is.EqualTo(entity.LastName)); + Assert.That(dateOfBirth, Is.EqualTo(entity.DateOfBirth)); } [TestCase("01/20/2012", "06/20/2018", 5)] @@ -191,17 +191,17 @@ public async Task DbSetCreatedFromCollectionCreateUser1(string firstName, string [TestCase("01/20/2010", "02/20/2011", 0)] public async Task DbSetGetUserReports(DateTime from, DateTime to, int expectedCount) { - // arrange - var users = CreateUserList(); - var mock = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); + // arrange + var users = CreateUserList(); + var mock = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); - // act - var result = await service.GetUserReports(from, to); + // act + var result = await service.GetUserReports(from, to); - // assert - Assert.That(expectedCount, Is.EqualTo(result.Count)); + // assert + Assert.That(expectedCount, Is.EqualTo(result.Count)); } [TestCase("01/20/2012", "06/20/2018", 5)] @@ -210,163 +210,204 @@ public async Task DbSetGetUserReports(DateTime from, DateTime to, int expectedCo [TestCase("01/20/2010", "02/20/2011", 0)] public async Task DbSetCreatedFromCollectionGetUserReports(DateTime from, DateTime to, int expectedCount) { - // arrange - var users = CreateUserList(); - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); + // arrange + var users = CreateUserList(); + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); - // act - var result = await service.GetUserReports(from, to); + // act + var result = await service.GetUserReports(from, to); - // assert - Assert.That(expectedCount, Is.EqualTo(result.Count)); + // assert + Assert.That(expectedCount, Is.EqualTo(result.Count)); } [TestCase] public async Task DbSetGetAllUserEntitiesAsync() { - // arrange - var users = CreateUserList(); + // arrange + var users = CreateUserList(); - var mockDbSet = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet); + var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); - // act - var result = await userRepository.GetAllAsync().ToListAsync(); + // act + var result = await userRepository.GetAllAsync().ToListAsync(); - // assert - Assert.That(users.Count, Is.EqualTo(result.Count)); + // assert + Assert.That(users.Count, Is.EqualTo(result.Count)); } [TestCase] public async Task DbSetCreatedFromCollectionGetAllUserEntitiesAsync() { - // arrange - var users = CreateUserList(); + // arrange + var users = CreateUserList(); - var mockDbSet = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet); + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); - // act - var result = await userRepository.GetAllAsync().ToListAsync(); + // act + var result = await userRepository.GetAllAsync().ToListAsync(); - // assert - Assert.That(users.Count, Is.EqualTo(result.Count)); + // assert + Assert.That(users.Count, Is.EqualTo(result.Count)); } [TestCase] public async Task DbSetToListAsyncAsync_ShouldReturnAllEntities_WhenSourceIsChanged() { - // arrange - var users = new List(); + // arrange + var users = new List(); - var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var mockDbSet = users.AsQueryable().BuildMockDbSet(); - // act - var result1 = await mockDbSet.ToListAsync(); - users.AddRange(CreateUserList()); - var result2 = await mockDbSet.ToListAsync(); + // act + var result1 = await mockDbSet.ToListAsync(); + users.AddRange(CreateUserList()); + var result2 = await mockDbSet.ToListAsync(); - // assert - Assert.That(0, Is.EqualTo(result1.Count)); - Assert.That(users.Count, Is.EqualTo(result2.Count)); + // assert + Assert.That(0, Is.EqualTo(result1.Count)); + Assert.That(users.Count, Is.EqualTo(result2.Count)); } [TestCase] public async Task DbSetGetAllUserEntity() { - //arrange - var users = CreateUserList(); - var mock = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); + //arrange + var users = CreateUserList(); + var mock = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); - //act - var result = await userRepository.GetAll(); + //act + var result = await userRepository.GetAll(); - //assert - Assert.That(users.Count, Is.EqualTo(result.Count)); + //assert + Assert.That(users.Count, Is.EqualTo(result.Count)); } [TestCase] public async Task DbSetCreatedFromCollectionGetAllUserEntity() { - // arrange - var users = CreateUserList(); - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); + // arrange + var users = CreateUserList(); + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); - // act - var result = await userRepository.GetAll(); + // act + var result = await userRepository.GetAll(); - // assert - Assert.That(users.Count, Is.EqualTo(result.Count)); + // assert + Assert.That(users.Count, Is.EqualTo(result.Count)); } [TestCase] public void GetUsersByFirstName_ExpressionVisitorMissing_ThrowsException() { - // arrange - var users = CreateUserList(); - - var mockDbSet = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet); - - // act - var exception = Assert.ThrowsAsync(() => userRepository.GetUsersByFirstName("naME")); - - // assert - Assert.That( - exception.Message, - Is.EqualTo( - "The 'ILike' method is not supported because the query has switched to client-evaluation. " + - "This usually happens when the arguments to the method cannot be translated to server. " + - "Rewrite the query to avoid client evaluation of arguments so that method can be translated to server.")); + // arrange + var users = CreateUserList(); + + var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); + + // act + var exception = Assert.ThrowsAsync(() => userRepository.GetUsersByFirstName("naME")); + + // assert + Assert.That( + exception.Message, + Is.EqualTo( + "The 'Like' method is not supported because the query has switched to client-evaluation. " + + "This usually happens when the arguments to the method cannot be translated to server. " + + "Rewrite the query to avoid client evaluation of arguments so that method can be translated to server.")); } [TestCase] public async Task GetUsersByFirstName_PartOfNameCaseInsensitiveSearch_AllMatchesReturned() { - // arrange - var users = CreateUserList(); + // arrange + var users = CreateUserList(); - var mockDbSet = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet); + var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); - // act - var result = await userRepository.GetUsersByFirstName("naME"); + // act + var result = await userRepository.GetUsersByFirstName("naME3"); - // assert - Assert.That(users.Count, Is.EqualTo(result.Count())); + // assert + Assert.That(result.Count, Is.EqualTo(2)); } - private static List CreateUserList() => new() + [TestCase] + public void GetUsersByLastName_ExpressionVisitorMissing_ThrowsException() + { + // arrange + var users = CreateUserList(); + + var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); + + // act + var exception = Assert.ThrowsAsync(() => userRepository.GetUsersByLastName("naME4")); + + // assert + Assert.That( + exception.Message, + Is.EqualTo( + "The 'ILike' method is not supported because the query has switched to client-evaluation. " + + "This usually happens when the arguments to the method cannot be translated to server. " + + "Rewrite the query to avoid client evaluation of arguments so that method can be translated to server.")); + } + + [TestCase] + public async Task GetUsersByLastName_PartOfNameCaseInsensitiveSearch_AllMatchesReturned() { - new UserEntity - { - FirstName = "FirstName1", LastName = "LastName", - DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) - }, - new UserEntity - { - FirstName = "FirstName2", LastName = "LastName", - DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) - }, - new UserEntity - { - FirstName = "FirstName3", LastName = "LastName", - DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) - }, - new UserEntity - { - FirstName = "FirstName3", LastName = "LastName", - DateOfBirth = DateTime.Parse("03/20/2012", UsCultureInfo.DateTimeFormat) - }, - new UserEntity - { - FirstName = "FirstName5", LastName = "LastName", - DateOfBirth = DateTime.Parse("01/20/2018", UsCultureInfo.DateTimeFormat) - }, - }; - } -} + // arrange + var users = CreateUserList(); + + var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); + + // act + var result = await userRepository.GetUsersByLastName("naME4"); + + // assert + Assert.That(result.Count, Is.EqualTo(3)); + } + + private static List CreateUserList() => + [ + new UserEntity + { + FirstName = "FirstName1", LastName = "LastName1", + DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) + }, + + new UserEntity + { + FirstName = "FirstName2", LastName = "LastName2", + DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) + }, + + new UserEntity + { + FirstName = "FirstName3", LastName = "LastName4", + DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) + }, + + new UserEntity + { + FirstName = "FirstName3", LastName = "LastName4", + DateOfBirth = DateTime.Parse("03/20/2012", UsCultureInfo.DateTimeFormat) + }, + + new UserEntity + { + FirstName = "FirstName5", LastName = "LastName4", + DateOfBirth = DateTime.Parse("01/20/2018", UsCultureInfo.DateTimeFormat) + } + + ]; +} \ No newline at end of file diff --git a/src/MockQueryable/MockQueryable.Sample/MyServiceMoqTests.cs b/src/MockQueryable/MockQueryable.Sample/MyServiceMoqTests.cs index 99da01d..d7de439 100644 --- a/src/MockQueryable/MockQueryable.Sample/MyServiceMoqTests.cs +++ b/src/MockQueryable/MockQueryable.Sample/MyServiceMoqTests.cs @@ -9,11 +9,11 @@ using Moq; using NUnit.Framework; -namespace MockQueryable.Sample +namespace MockQueryable.Sample; + +[TestFixture] +public class MyServiceMoqTests { - [TestFixture] - public class MyServiceMoqTests - { private static readonly CultureInfo UsCultureInfo = new("en-US"); [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] @@ -21,25 +21,25 @@ public class MyServiceMoqTests [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] public void CreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) { - //arrange - var userRepository = new Mock(); - var service = new MyService(userRepository.Object); - var users = new List - { - new() {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, - new() {FirstName = "ExistFirstName"}, - new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, - new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, - new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)} - }; - //expect - var mock = users.BuildMock(); - userRepository.Setup(x => x.GetQueryable()).Returns(mock); - //act - var ex = Assert.ThrowsAsync(() => - service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); - //assert - Assert.That(expectedError, Is.EqualTo(ex.Message)); + //arrange + var userRepository = new Mock(); + var service = new MyService(userRepository.Object); + var users = new List + { + new() {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {FirstName = "ExistFirstName"}, + new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)} + }; + //expect + var mock = users.BuildMock(); + userRepository.Setup(x => x.GetQueryable()).Returns(mock); + //act + var ex = Assert.ThrowsAsync(() => + service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); + //assert + Assert.That(expectedError, Is.EqualTo(ex.Message)); } [TestCase("01/20/2012", "06/20/2018", 5)] @@ -48,17 +48,17 @@ public void CreateUserIfNotExist(string firstName, string lastName, DateTime dat [TestCase("01/20/2010", "02/20/2011", 0)] public async Task GetUserReports(DateTime from, DateTime to, int expectedCount) { - //arrange - var userRepository = new Mock(); - var service = new MyService(userRepository.Object); - var users = CreateUserList(); - //expect - var mock = users.BuildMock(); - userRepository.Setup(x => x.GetQueryable()).Returns(mock); - //act - var result = await service.GetUserReports(from, to); - //assert - Assert.That(expectedCount, Is.EqualTo(result.Count)); + //arrange + var userRepository = new Mock(); + var service = new MyService(userRepository.Object); + var users = CreateUserList(); + //expect + var mock = users.BuildMock(); + userRepository.Setup(x => x.GetQueryable()).Returns(mock); + //act + var result = await service.GetUserReports(from, to); + //assert + Assert.That(expectedCount, Is.EqualTo(result.Count)); } [TestCase("01/20/2012", "06/20/2018", 5)] @@ -67,17 +67,17 @@ public async Task GetUserReports(DateTime from, DateTime to, int expectedCount) [TestCase("01/20/2010", "02/20/2011", 0)] public async Task GetUserReports_AutoMap(DateTime from, DateTime to, int expectedCount) { - //arrange - var userRepository = new Mock(); - var service = new MyService(userRepository.Object); - var users = CreateUserList(); - //expect - var mock = users.BuildMock(); - userRepository.Setup(x => x.GetQueryable()).Returns(mock); - //act - var result = await service.GetUserReportsAutoMap(from, to); - //assert - Assert.That(expectedCount, Is.EqualTo(result.Count)); + //arrange + var userRepository = new Mock(); + var service = new MyService(userRepository.Object); + var users = CreateUserList(); + //expect + var mock = users.BuildMock(); + userRepository.Setup(x => x.GetQueryable()).Returns(mock); + //act + var result = await service.GetUserReportsAutoMap(from, to); + //assert + Assert.That(expectedCount, Is.EqualTo(result.Count)); } [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] @@ -85,23 +85,23 @@ public async Task GetUserReports_AutoMap(DateTime from, DateTime to, int expecte [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] public void DbSetCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) { - //arrange - var users = new List - { - new() {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, - new() {FirstName = "ExistFirstName"}, - new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, - new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, - new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)} - }; - var mock = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock.Object); - var service = new MyService(userRepository); - //act - var ex = Assert.ThrowsAsync(() => - service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); - //assert - Assert.That(expectedError, Is.EqualTo(ex.Message)); + //arrange + var users = new List + { + new() {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {FirstName = "ExistFirstName"}, + new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, + new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)} + }; + var mock = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock.Object); + var service = new MyService(userRepository); + //act + var ex = Assert.ThrowsAsync(() => + service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); + //assert + Assert.That(expectedError, Is.EqualTo(ex.Message)); } [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] @@ -109,8 +109,8 @@ public void DbSetCreateUserIfNotExist(string firstName, string lastName, DateTim [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] public void DbSetCreatedFromCollectionCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) { - //arrange - var users = new List + //arrange + var users = new List { new() {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, new() {FirstName = "ExistFirstName"}, @@ -118,54 +118,54 @@ public void DbSetCreatedFromCollectionCreateUserIfNotExist(string firstName, str new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, new() {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)} }; - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock.Object); - var service = new MyService(userRepository); - //act - var ex = Assert.ThrowsAsync(() => - service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); - //assert - Assert.That(expectedError, Is.EqualTo(ex.Message)); + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock.Object); + var service = new MyService(userRepository); + //act + var ex = Assert.ThrowsAsync(() => + service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); + //assert + Assert.That(expectedError, Is.EqualTo(ex.Message)); } [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] public async Task DbSetCreateUser(string firstName, string lastName, DateTime dateOfBirth) { - //arrange - var userEntities = new List(); - var mock = userEntities.AsQueryable().BuildMockDbSet(); - - mock.Setup(set => set.AddAsync(It.IsAny(), It.IsAny())) - .Callback((UserEntity entity, CancellationToken _) => userEntities.Add(entity)); - var userRepository = new TestDbSetRepository(mock.Object); - var service = new MyService(userRepository); - //act - await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); - // assert - var entity = mock.Object.Single(); - Assert.That(firstName, Is.EqualTo(entity.FirstName)); - Assert.That(lastName, Is.EqualTo(entity.LastName)); - Assert.That(dateOfBirth, Is.EqualTo(entity.DateOfBirth)); + //arrange + var userEntities = new List(); + var mock = userEntities.AsQueryable().BuildMockDbSet(); + + mock.Setup(set => set.AddAsync(It.IsAny(), It.IsAny())) + .Callback((UserEntity entity, CancellationToken _) => userEntities.Add(entity)); + var userRepository = new TestDbSetRepository(mock.Object); + var service = new MyService(userRepository); + //act + await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); + // assert + var entity = mock.Object.Single(); + Assert.That(firstName, Is.EqualTo(entity.FirstName)); + Assert.That(lastName, Is.EqualTo(entity.LastName)); + Assert.That(dateOfBirth, Is.EqualTo(entity.DateOfBirth)); } [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] public async Task DbSetCreatedFromCollectionCreateUser(string firstName, string lastName, DateTime dateOfBirth) { - //arrange - var userEntities = new List(); - var mock = userEntities.BuildMockDbSet(); - - mock.Setup(set => set.AddAsync(It.IsAny(), It.IsAny())) - .Callback((UserEntity entity, CancellationToken _) => userEntities.Add(entity)); - var userRepository = new TestDbSetRepository(mock.Object); - var service = new MyService(userRepository); - //act - await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); - // assert - var entity = mock.Object.Single(); - Assert.That(firstName, Is.EqualTo(entity.FirstName)); - Assert.That(lastName, Is.EqualTo(entity.LastName)); - Assert.That(dateOfBirth, Is.EqualTo(entity.DateOfBirth)); + //arrange + var userEntities = new List(); + var mock = userEntities.BuildMockDbSet(); + + mock.Setup(set => set.AddAsync(It.IsAny(), It.IsAny())) + .Callback((UserEntity entity, CancellationToken _) => userEntities.Add(entity)); + var userRepository = new TestDbSetRepository(mock.Object); + var service = new MyService(userRepository); + //act + await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); + // assert + var entity = mock.Object.Single(); + Assert.That(firstName, Is.EqualTo(entity.FirstName)); + Assert.That(lastName, Is.EqualTo(entity.LastName)); + Assert.That(dateOfBirth, Is.EqualTo(entity.DateOfBirth)); } [TestCase("01/20/2012", "06/20/2018", 5)] @@ -174,15 +174,15 @@ public async Task DbSetCreatedFromCollectionCreateUser(string firstName, string [TestCase("01/20/2010", "02/20/2011", 0)] public async Task DbSetGetUserReports(DateTime from, DateTime to, int expectedCount) { - //arrange - var users = CreateUserList(); - var mock = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock.Object); - var service = new MyService(userRepository); - //act - var result = await service.GetUserReports(from, to); - //assert - Assert.That(expectedCount, Is.EqualTo(result.Count)); + //arrange + var users = CreateUserList(); + var mock = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock.Object); + var service = new MyService(userRepository); + //act + var result = await service.GetUserReports(from, to); + //assert + Assert.That(expectedCount, Is.EqualTo(result.Count)); } [TestCase("01/20/2012", "06/20/2018", 5)] @@ -191,99 +191,99 @@ public async Task DbSetGetUserReports(DateTime from, DateTime to, int expectedCo [TestCase("01/20/2010", "02/20/2011", 0)] public async Task DbSetCreatedFromCollectionGetUserReports(DateTime from, DateTime to, int expectedCount) { - //arrange - var users = CreateUserList(); - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock.Object); - var service = new MyService(userRepository); - //act - var result = await service.GetUserReports(from, to); - //assert - Assert.That(expectedCount, Is.EqualTo(result.Count)); + //arrange + var users = CreateUserList(); + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock.Object); + var service = new MyService(userRepository); + //act + var result = await service.GetUserReports(from, to); + //assert + Assert.That(expectedCount, Is.EqualTo(result.Count)); } [TestCase] public async Task DbSetGetAllUserEntity() { - //arrange - var users = CreateUserList(); - var mock = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock.Object); - //act - var result = await userRepository.GetAll(); - //assert - Assert.That(users.Count, Is.EqualTo(result.Count)); + //arrange + var users = CreateUserList(); + var mock = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock.Object); + //act + var result = await userRepository.GetAll(); + //assert + Assert.That(users.Count, Is.EqualTo(result.Count)); } [TestCase] public async Task DbSetCreatedFromCollectionGetAllUserEntity() { - //arrange - var users = CreateUserList(); - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock.Object); - //act - var result = await userRepository.GetAll(); - //assert - Assert.That(users.Count, Is.EqualTo(result.Count)); + //arrange + var users = CreateUserList(); + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock.Object); + //act + var result = await userRepository.GetAll(); + //assert + Assert.That(users.Count, Is.EqualTo(result.Count)); } [TestCase] public async Task DbSetFindAsyncUserEntity() { - //arrange - var userId = Guid.NewGuid(); - var users = new List - { - new() { - Id = Guid.NewGuid(), - FirstName = "FirstName1", LastName = "LastName", - DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) - }, - new() { - Id = Guid.NewGuid(), - FirstName = "FirstName2", LastName = "LastName", - DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) - }, - new() { - Id = userId, - FirstName = "FirstName3", LastName = "LastName", - DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) - }, - new() { - Id = Guid.NewGuid(), - FirstName = "FirstName3", LastName = "LastName", - DateOfBirth = DateTime.Parse("03/20/2012", UsCultureInfo.DateTimeFormat) - }, - new() { - Id = Guid.NewGuid(), - FirstName = "FirstName5", LastName = "LastName", - DateOfBirth = DateTime.Parse("01/20/2018", UsCultureInfo.DateTimeFormat) - } - }; - - var mock = users.AsQueryable().BuildMockDbSet(); - mock.Setup(x => x.FindAsync(It.IsAny())).ReturnsAsync((object[] ids) => - { - var id = (Guid)ids.First(); - return users.FirstOrDefault(x => x.Id == id); - }); - var userRepository = new TestDbSetRepository(mock.Object); - - //act - var result = await ((DbSet)userRepository.GetQueryable()).FindAsync(userId); - - //assert - Assert.That(result, Is.Not.Null); - Assert.That("FirstName3", Is.EqualTo(result.FirstName)); + //arrange + var userId = Guid.NewGuid(); + var users = new List + { + new() { + Id = Guid.NewGuid(), + FirstName = "FirstName1", LastName = "LastName", + DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) + }, + new() { + Id = Guid.NewGuid(), + FirstName = "FirstName2", LastName = "LastName", + DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) + }, + new() { + Id = userId, + FirstName = "FirstName3", LastName = "LastName", + DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) + }, + new() { + Id = Guid.NewGuid(), + FirstName = "FirstName3", LastName = "LastName", + DateOfBirth = DateTime.Parse("03/20/2012", UsCultureInfo.DateTimeFormat) + }, + new() { + Id = Guid.NewGuid(), + FirstName = "FirstName5", LastName = "LastName", + DateOfBirth = DateTime.Parse("01/20/2018", UsCultureInfo.DateTimeFormat) + } + }; + + var mock = users.AsQueryable().BuildMockDbSet(); + mock.Setup(x => x.FindAsync(It.IsAny())).ReturnsAsync((object[] ids) => + { + var id = (Guid)ids.First(); + return users.FirstOrDefault(x => x.Id == id); + }); + var userRepository = new TestDbSetRepository(mock.Object); + + //act + var result = await ((DbSet)userRepository.GetQueryable()).FindAsync(userId); + + //assert + Assert.That(result, Is.Not.Null); + Assert.That("FirstName3", Is.EqualTo(result.FirstName)); } [TestCase] public async Task DbSetCreatedFromCollectionFindAsyncUserEntity() { - //arrange - var userId = Guid.NewGuid(); - var users = new List + //arrange + var userId = Guid.NewGuid(); + var users = new List { new() { Id = Guid.NewGuid(), @@ -312,116 +312,178 @@ public async Task DbSetCreatedFromCollectionFindAsyncUserEntity() } }; - var mock = users.BuildMockDbSet(); - mock.Setup(x => x.FindAsync(It.IsAny())).ReturnsAsync((object[] ids) => - { - var id = (Guid)ids.First(); - return users.FirstOrDefault(x => x.Id == id); - }); - var userRepository = new TestDbSetRepository(mock.Object); + var mock = users.BuildMockDbSet(); + mock.Setup(x => x.FindAsync(It.IsAny())).ReturnsAsync((object[] ids) => + { + var id = (Guid)ids.First(); + return users.FirstOrDefault(x => x.Id == id); + }); + var userRepository = new TestDbSetRepository(mock.Object); - //act - var result = await ((DbSet)userRepository.GetQueryable()).FindAsync(userId); + //act + var result = await ((DbSet)userRepository.GetQueryable()).FindAsync(userId); - //assert - Assert.That(result, Is.Not.Null); - Assert.That("FirstName3", Is.EqualTo(result.FirstName)); + //assert + Assert.That(result, Is.Not.Null); + Assert.That("FirstName3", Is.EqualTo(result.FirstName)); } [TestCase] public async Task DbSetGetAllUserEntitiesAsync() { - // arrange - var users = CreateUserList(); + // arrange + var users = CreateUserList(); - var mockDbSet = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet.Object); + var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet.Object); - // act - var result = await userRepository.GetAllAsync().ToListAsync(); + // act + var result = await userRepository.GetAllAsync().ToListAsync(); - // assert - Assert.That(users.Count, Is.EqualTo(result.Count)); + // assert + Assert.That(users.Count, Is.EqualTo(result.Count)); } [TestCase] public async Task DbSetToListAsyncAsync_ShouldReturnAllEntities_WhenSourceIsChanged() { - // arrange - var users = new List(); + // arrange + var users = new List(); - var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var mockDbSet = users.AsQueryable().BuildMockDbSet(); - // act - var result1 = await mockDbSet.Object.ToListAsync(); - users.AddRange(CreateUserList()); - var result2 = await mockDbSet.Object.ToListAsync(); + // act + var result1 = await mockDbSet.Object.ToListAsync(); + users.AddRange(CreateUserList()); + var result2 = await mockDbSet.Object.ToListAsync(); - // assert - Assert.That(0, Is.EqualTo(result1.Count)); - Assert.That(users.Count, Is.EqualTo(result2.Count)); + // assert + Assert.That(0, Is.EqualTo(result1.Count)); + Assert.That(users.Count, Is.EqualTo(result2.Count)); } [TestCase] public async Task DbSetCreatedFromCollectionGetAllUserEntitiesAsync() { - // arrange - var users = CreateUserList(); + // arrange + var users = CreateUserList(); - var mockDbSet = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet.Object); + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet.Object); - // act - var result = await userRepository.GetAllAsync().ToListAsync(); + // act + var result = await userRepository.GetAllAsync().ToListAsync(); - // assert - Assert.That(users.Count, Is.EqualTo(result.Count)); + // assert + Assert.That(users.Count, Is.EqualTo(result.Count)); } [TestCase] public void GetUsersByFirstName_ExpressionVisitorMissing_ThrowsException() { - // arrange - var users = CreateUserList(); - - var mockDbSet = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet.Object); - - // act - var exception = Assert.ThrowsAsync(() => userRepository.GetUsersByFirstName("naME")); - - // assert - Assert.That( - exception.Message, - Is.EqualTo( - "The 'ILike' method is not supported because the query has switched to client-evaluation. " + - "This usually happens when the arguments to the method cannot be translated to server. " + - "Rewrite the query to avoid client evaluation of arguments so that method can be translated to server.")); + // arrange + var users = CreateUserList(); + + var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet.Object); + + // act + var exception = Assert.ThrowsAsync(() => userRepository.GetUsersByFirstName("naME4")); + + // assert + Assert.That( + exception.Message, + Is.EqualTo( + "The 'Like' method is not supported because the query has switched to client-evaluation. " + + "This usually happens when the arguments to the method cannot be translated to server. " + + "Rewrite the query to avoid client evaluation of arguments so that method can be translated to server.")); } + [TestCase] public async Task GetUsersByFirstName_PartOfNameCaseInsensitiveSearch_AllMatchesReturned() { - // arrange - var users = CreateUserList(); + // arrange + var users = CreateUserList(); - var mockDbSet = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet.Object); + var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet.Object); - // act - var result = await userRepository.GetUsersByFirstName("naME"); + // act + var result = await userRepository.GetUsersByFirstName("naME3"); - // assert - Assert.That(users.Count, Is.EqualTo(result.Count())); + // assert + Assert.That(result.Count(), Is.EqualTo(2)); } - private static List CreateUserList() => new() + [TestCase] + public void GetUsersByLastName_ExpressionVisitorMissing_ThrowsException() { - new UserEntity { FirstName = "FirstName1", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, - new UserEntity { FirstName = "FirstName2", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, - new UserEntity { FirstName = "FirstName3", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, - new UserEntity { FirstName = "FirstName3", LastName = "LastName", DateOfBirth = DateTime.Parse("03/20/2012", UsCultureInfo.DateTimeFormat) }, - new UserEntity { FirstName = "FirstName5", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2018", UsCultureInfo.DateTimeFormat) }, - }; - } + // arrange + var users = CreateUserList(); + + var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet.Object); + + // act + var exception = Assert.ThrowsAsync(() => userRepository.GetUsersByLastName("naME4")); + + // assert + Assert.That( + exception.Message, + Is.EqualTo( + "The 'ILike' method is not supported because the query has switched to client-evaluation. " + + "This usually happens when the arguments to the method cannot be translated to server. " + + "Rewrite the query to avoid client evaluation of arguments so that method can be translated to server.")); + } + + [TestCase] + public async Task GetUsersByLastName_PartOfNameCaseInsensitiveSearch_AllMatchesReturned() + { + // arrange + var users = CreateUserList(); + + var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet.Object); + + // act + var result = await userRepository.GetUsersByLastName("naME4"); + + // assert + Assert.That(result.Count(), Is.EqualTo(3)); + } + + private static List CreateUserList() => + [ + new UserEntity + { + FirstName = "FirstName1", LastName = "LastName1", + DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) + }, + + new UserEntity + { + FirstName = "FirstName2", LastName = "LastName2", + DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) + }, + + new UserEntity + { + FirstName = "FirstName3", LastName = "LastName4", + DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) + }, + + new UserEntity + { + FirstName = "FirstName3", LastName = "LastName4", + DateOfBirth = DateTime.Parse("03/20/2012", UsCultureInfo.DateTimeFormat) + }, + + new UserEntity + { + FirstName = "FirstName5", LastName = "LastName4", + DateOfBirth = DateTime.Parse("01/20/2018", UsCultureInfo.DateTimeFormat) + } + + ]; } \ No newline at end of file diff --git a/src/MockQueryable/MockQueryable.Sample/MyServiceNSubstituteTests.cs b/src/MockQueryable/MockQueryable.Sample/MyServiceNSubstituteTests.cs index b9b8509..81a34a5 100644 --- a/src/MockQueryable/MockQueryable.Sample/MyServiceNSubstituteTests.cs +++ b/src/MockQueryable/MockQueryable.Sample/MyServiceNSubstituteTests.cs @@ -7,11 +7,11 @@ using System.Linq; using System.Threading.Tasks; -namespace MockQueryable.Sample +namespace MockQueryable.Sample; + +[TestFixture] +public class MyServiceNSubstituteTests { - [TestFixture] - public class MyServiceNSubstituteTests - { private static readonly CultureInfo UsCultureInfo = new("en-US"); [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] @@ -19,24 +19,28 @@ public class MyServiceNSubstituteTests [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] public void CreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) { - //arrange - var userRepository = Substitute.For(); - var service = new MyService(userRepository); - var users = new List - { - new() {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, - new() {FirstName = "ExistFirstName"}, - new() {DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, - new() {DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, - new() {DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, - }; - //expect - var mock = users.BuildMock(); - userRepository.GetQueryable().Returns(mock); - //act - var ex = Assert.ThrowsAsync(() => service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); - //assert - Assert.That(expectedError, Is.EqualTo(ex.Message)); + //arrange + var userRepository = Substitute.For(); + var service = new MyService(userRepository); + var users = new List + { + new() + { + LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) + }, + new() { FirstName = "ExistFirstName" }, + new() { DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, + new() { DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, + new() { DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, + }; + //expect + var mock = users.BuildMock(); + userRepository.GetQueryable().Returns(mock); + //act + var ex = Assert.ThrowsAsync(() => + service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); + //assert + Assert.That(expectedError, Is.EqualTo(ex.Message)); } [TestCase("01/20/2012", "06/20/2018", 5)] @@ -45,18 +49,18 @@ public void CreateUserIfNotExist(string firstName, string lastName, DateTime dat [TestCase("01/20/2010", "02/20/2011", 0)] public async Task GetUserReports(DateTime from, DateTime to, int expectedCount) { - //arrange - var userRepository = Substitute.For(); - var service = new MyService(userRepository); - List users = CreateUserList(); - - //expect - var mock = users.BuildMock(); - userRepository.GetQueryable().Returns(mock); - //act - var result = await service.GetUserReports(from, to); - //assert - Assert.That(expectedCount, Is.EqualTo(result.Count)); + //arrange + var userRepository = Substitute.For(); + var service = new MyService(userRepository); + List users = CreateUserList(); + + //expect + var mock = users.BuildMock(); + userRepository.GetQueryable().Returns(mock); + //act + var result = await service.GetUserReports(from, to); + //assert + Assert.That(expectedCount, Is.EqualTo(result.Count)); } [TestCase("01/20/2012", "06/20/2018", 5)] @@ -65,120 +69,131 @@ public async Task GetUserReports(DateTime from, DateTime to, int expectedCount) [TestCase("01/20/2010", "02/20/2011", 0)] public async Task GetUserReports_AutoMap(DateTime from, DateTime to, int expectedCount) { - //arrange - List users = CreateUserList(); - - var mock = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - //act - var result = await service.GetUserReportsAutoMap(from, to); - //assert - Assert.That(expectedCount, Is.EqualTo(result.Count)); + //arrange + List users = CreateUserList(); + + var mock = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + //act + var result = await service.GetUserReportsAutoMap(from, to); + //assert + Assert.That(expectedCount, Is.EqualTo(result.Count)); } [TestCase("01/20/2012", "06/20/2018", 5)] [TestCase("01/20/2012", "06/20/2012", 4)] [TestCase("01/20/2012", "02/20/2012", 3)] [TestCase("01/20/2010", "02/20/2011", 0)] - public async Task GetUserReports_AutoMap_FromDbSetCreatedFromCollection(DateTime from, DateTime to, int expectedCount) + public async Task GetUserReports_AutoMap_FromDbSetCreatedFromCollection(DateTime from, DateTime to, + int expectedCount) { - //arrange - List users = CreateUserList(); - - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - //act - var result = await service.GetUserReportsAutoMap(from, to); - //assert - Assert.That(expectedCount, Is.EqualTo(result.Count)); + //arrange + List users = CreateUserList(); + + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + //act + var result = await service.GetUserReportsAutoMap(from, to); + //assert + Assert.That(expectedCount, Is.EqualTo(result.Count)); } [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] - public void DbSetCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) + public void DbSetCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, + string expectedError) { - //arrange - var users = new List + //arrange + var users = new List + { + new() { - new() {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, - new() {FirstName = "ExistFirstName"}, - new() {DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, - new() {DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, - new() {DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, - }; - var mock = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - //act - var ex = Assert.ThrowsAsync(() => service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); - //assert - Assert.That(expectedError, Is.EqualTo(ex.Message)); + LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) + }, + new() { FirstName = "ExistFirstName" }, + new() { DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, + new() { DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, + new() { DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, + }; + var mock = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + //act + var ex = Assert.ThrowsAsync(() => + service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); + //assert + Assert.That(expectedError, Is.EqualTo(ex.Message)); } [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] - public void DbSetCreatedFromCollectionCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) + public void DbSetCreatedFromCollectionCreateUserIfNotExist(string firstName, string lastName, + DateTime dateOfBirth, string expectedError) { - //arrange - var users = new List + //arrange + var users = new List + { + new() { - new() {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, - new() {FirstName = "ExistFirstName"}, - new() {DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, - new() {DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, - new() {DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, - }; - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - //act - var ex = Assert.ThrowsAsync(() => service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); - //assert - Assert.That(expectedError, Is.EqualTo(ex.Message)); + LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) + }, + new() { FirstName = "ExistFirstName" }, + new() { DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, + new() { DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, + new() { DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, + }; + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + //act + var ex = Assert.ThrowsAsync(() => + service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); + //assert + Assert.That(expectedError, Is.EqualTo(ex.Message)); } [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] public async Task DbSetCreateUser(string firstName, string lastName, DateTime dateOfBirth) { - //arrange - var userEntities = new List(); - var mock = userEntities.AsQueryable().BuildMockDbSet(); - mock.AddAsync(Arg.Any()) - .Returns(info => null) - .AndDoes(info => userEntities.Add(info.Arg())); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - //act - await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); - // assert - var entity = mock.Single(); - Assert.That(firstName, Is.EqualTo(entity.FirstName)); - Assert.That(lastName, Is.EqualTo(entity.LastName)); - Assert.That(dateOfBirth, Is.EqualTo(entity.DateOfBirth)); + //arrange + var userEntities = new List(); + var mock = userEntities.AsQueryable().BuildMockDbSet(); + mock.AddAsync(Arg.Any()) + .Returns(info => null) + .AndDoes(info => userEntities.Add(info.Arg())); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + //act + await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); + // assert + var entity = mock.Single(); + Assert.That(firstName, Is.EqualTo(entity.FirstName)); + Assert.That(lastName, Is.EqualTo(entity.LastName)); + Assert.That(dateOfBirth, Is.EqualTo(entity.DateOfBirth)); } [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] public async Task DbSetCreatedFromCollectionCreateUser(string firstName, string lastName, DateTime dateOfBirth) { - //arrange - var userEntities = new List(); - var mock = userEntities.BuildMockDbSet(); - mock.AddAsync(Arg.Any()) - .Returns(info => null) - .AndDoes(info => userEntities.Add(info.Arg())); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - //act - await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); - // assert - var entity = mock.Single(); - Assert.That(firstName, Is.EqualTo(entity.FirstName)); - Assert.That(lastName, Is.EqualTo(entity.LastName)); - Assert.That(dateOfBirth, Is.EqualTo(entity.DateOfBirth)); + //arrange + var userEntities = new List(); + var mock = userEntities.BuildMockDbSet(); + mock.AddAsync(Arg.Any()) + .Returns(info => null) + .AndDoes(info => userEntities.Add(info.Arg())); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + //act + await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); + // assert + var entity = mock.Single(); + Assert.That(firstName, Is.EqualTo(entity.FirstName)); + Assert.That(lastName, Is.EqualTo(entity.LastName)); + Assert.That(dateOfBirth, Is.EqualTo(entity.DateOfBirth)); } [TestCase("01/20/2012", "06/20/2018", 5)] @@ -187,16 +202,16 @@ public async Task DbSetCreatedFromCollectionCreateUser(string firstName, string [TestCase("01/20/2010", "02/20/2011", 0)] public async Task DbSetGetUserReports(DateTime from, DateTime to, int expectedCount) { - //arrange - var users = CreateUserList(); - - var mock = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - //act - var result = await service.GetUserReports(from, to); - //assert - Assert.That(expectedCount, Is.EqualTo(result.Count)); + //arrange + var users = CreateUserList(); + + var mock = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + //act + var result = await service.GetUserReports(from, to); + //assert + Assert.That(expectedCount, Is.EqualTo(result.Count)); } [TestCase("01/20/2012", "06/20/2018", 5)] @@ -205,175 +220,244 @@ public async Task DbSetGetUserReports(DateTime from, DateTime to, int expectedCo [TestCase("01/20/2010", "02/20/2011", 0)] public async Task DbSetCreatedFromCollectionGetUserReports(DateTime from, DateTime to, int expectedCount) { - //arrange - var users = CreateUserList(); - - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - var service = new MyService(userRepository); - //act - var result = await service.GetUserReports(from, to); - //assert - Assert.That(expectedCount, Is.EqualTo(result.Count)); + //arrange + var users = CreateUserList(); + + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + var service = new MyService(userRepository); + //act + var result = await service.GetUserReports(from, to); + //assert + Assert.That(expectedCount, Is.EqualTo(result.Count)); } [TestCase] public async Task DbSetGetAllUserEntity() { - //arrange - var users = CreateUserList(); - var mock = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - //act - var result = await userRepository.GetAll(); - //assert - Assert.That(users.Count, Is.EqualTo(result.Count)); + //arrange + var users = CreateUserList(); + var mock = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + //act + var result = await userRepository.GetAll(); + //assert + Assert.That(users.Count, Is.EqualTo(result.Count)); } [TestCase] public async Task DbSetCreatedFromCollectionGetAllUserEntity() { - //arrange - var users = CreateUserList(); - var mock = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mock); - //act - var result = await userRepository.GetAll(); - //assert - Assert.That(users.Count, Is.EqualTo(result.Count)); + //arrange + var users = CreateUserList(); + var mock = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mock); + //act + var result = await userRepository.GetAll(); + //assert + Assert.That(users.Count, Is.EqualTo(result.Count)); } [TestCase] public async Task DbSetGetAllUserEntitiesAsync() { - // arrange - var users = CreateUserList(); + // arrange + var users = CreateUserList(); - var mockDbSet = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet); + var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); - // act - var result = await userRepository.GetAllAsync().ToListAsync(); + // act + var result = await userRepository.GetAllAsync().ToListAsync(); - // assert - Assert.That(users.Count, Is.EqualTo(result.Count)); + // assert + Assert.That(users.Count, Is.EqualTo(result.Count)); } [TestCase] public async Task DbSetGetAllUserEntitiesAsync_ShouldReturnAllEntities_WhenSourceIsChanged() { - // arrange - var users = new List(); + // arrange + var users = new List(); - var mockDbSet = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet); + var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); - // act - var result1 = await userRepository.GetAllAsync().ToListAsync(); - users.AddRange(CreateUserList()); - var result2 = await userRepository.GetAllAsync().ToListAsync(); + // act + var result1 = await userRepository.GetAllAsync().ToListAsync(); + users.AddRange(CreateUserList()); + var result2 = await userRepository.GetAllAsync().ToListAsync(); - // assert - Assert.That(0, Is.EqualTo(result1.Count)); - Assert.That(users.Count, Is.EqualTo(result2.Count)); + // assert + Assert.That(0, Is.EqualTo(result1.Count)); + Assert.That(users.Count, Is.EqualTo(result2.Count)); } [TestCase] public async Task DbSetCreatedFromCollectionGetAllUserEntitiesAsync() { - // arrange - var users = CreateUserList(); + // arrange + var users = CreateUserList(); - var mockDbSet = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet); + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); - // act - var result = await userRepository.GetAllAsync().ToListAsync(); + // act + var result = await userRepository.GetAllAsync().ToListAsync(); - // assert - Assert.That(users.Count, Is.EqualTo(result.Count)); + // assert + Assert.That(users.Count, Is.EqualTo(result.Count)); } [TestCase] public async Task DbSetGetOneUserTntityAsync() { - // arrange - var users = CreateUserList(); + // arrange + var users = CreateUserList(); - var mockDbSet = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet); + var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); - // act - var result = await userRepository.GetAllAsync() - .Where(user => user.FirstName == "FirstName1") - .FirstOrDefaultAsync(); + // act + var result = await userRepository.GetAllAsync() + .Where(user => user.FirstName == "FirstName1") + .FirstOrDefaultAsync(); - // assert - Assert.That(users.First(), Is.EqualTo(result)); + // assert + Assert.That(users.First(), Is.EqualTo(result)); } [TestCase] public async Task DbSetCreatedFromCollectionGetOneUserTntityAsync() { - // arrange - var users = CreateUserList(); + // arrange + var users = CreateUserList(); - var mockDbSet = users.BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet); + var mockDbSet = users.BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); - // act - var result = await userRepository.GetAllAsync() - .Where(user => user.FirstName == "FirstName1") - .FirstOrDefaultAsync(); + // act + var result = await userRepository.GetAllAsync() + .Where(user => user.FirstName == "FirstName1") + .FirstOrDefaultAsync(); - // assert - Assert.That(users.First(), Is.EqualTo(result)); + // assert + Assert.That(users.First(), Is.EqualTo(result)); } [TestCase] public void GetUsersByFirstName_ExpressionVisitorMissing_ThrowsException() { - // arrange - var users = CreateUserList(); - - var mockDbSet = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet); - - // act - var exception = Assert.ThrowsAsync(() => userRepository.GetUsersByFirstName("naME")); - - // assert - Assert.That( - exception.Message, - Is.EqualTo( - "The 'ILike' method is not supported because the query has switched to client-evaluation. " + - "This usually happens when the arguments to the method cannot be translated to server. " + - "Rewrite the query to avoid client evaluation of arguments so that method can be translated to server.")); + // arrange + var users = CreateUserList(); + + var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); + + // act + var exception = + Assert.ThrowsAsync(() => userRepository.GetUsersByFirstName("naME")); + + // assert + Assert.That( + exception.Message, + Is.EqualTo( + "The 'Like' method is not supported because the query has switched to client-evaluation. " + + "This usually happens when the arguments to the method cannot be translated to server. " + + "Rewrite the query to avoid client evaluation of arguments so that method can be translated to server.")); } + + [TestCase] public async Task GetUsersByFirstName_PartOfNameCaseInsensitiveSearch_AllMatchesReturned() { - // arrange - var users = CreateUserList(); + // arrange + var users = CreateUserList(); - var mockDbSet = users.AsQueryable().BuildMockDbSet(); - var userRepository = new TestDbSetRepository(mockDbSet); + var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); - // act - var result = await userRepository.GetUsersByFirstName("naME"); + // act + var result = await userRepository.GetUsersByFirstName("naME3"); - // assert - Assert.That(users.Count, Is.EqualTo(result.Count())); + // assert + Assert.That(result.Count, Is.EqualTo(2)); } - private static List CreateUserList() => new() + + + [TestCase] + public void GetUsersByLastName_ExpressionVisitorMissing_ThrowsException() + { + // arrange + var users = CreateUserList(); + + var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); + + // act + var exception = + Assert.ThrowsAsync(() => userRepository.GetUsersByLastName("naME4")); + + // assert + Assert.That( + exception.Message, + Is.EqualTo( + "The 'ILike' method is not supported because the query has switched to client-evaluation. " + + "This usually happens when the arguments to the method cannot be translated to server. " + + "Rewrite the query to avoid client evaluation of arguments so that method can be translated to server.")); + } + + + + [TestCase] + public async Task GetUsersByLastName_PartOfNameCaseInsensitiveSearch_AllMatchesReturned() + { + // arrange + var users = CreateUserList(); + + var mockDbSet = users.AsQueryable().BuildMockDbSet(); + var userRepository = new TestDbSetRepository(mockDbSet); + + // act + var result = await userRepository.GetUsersByLastName("naME4"); + + // assert + Assert.That(result.Count, Is.EqualTo(3)); + } + + private static List CreateUserList() => + [ + new UserEntity { - new UserEntity { FirstName = "FirstName1", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, - new UserEntity { FirstName = "FirstName2", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, - new UserEntity { FirstName = "FirstName3", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, - new UserEntity { FirstName = "FirstName3", LastName = "LastName", DateOfBirth = DateTime.Parse("03/20/2012", UsCultureInfo.DateTimeFormat) }, - new UserEntity { FirstName = "FirstName5", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2018", UsCultureInfo.DateTimeFormat) }, - }; - } -} + FirstName = "FirstName1", LastName = "LastName1", + DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) + }, + + new UserEntity + { + FirstName = "FirstName2", LastName = "LastName2", + DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) + }, + + new UserEntity + { + FirstName = "FirstName3", LastName = "LastName4", + DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) + }, + + new UserEntity + { + FirstName = "FirstName3", LastName = "LastName4", + DateOfBirth = DateTime.Parse("03/20/2012", UsCultureInfo.DateTimeFormat) + }, + + new UserEntity + { + FirstName = "FirstName5", LastName = "LastName4", + DateOfBirth = DateTime.Parse("01/20/2018", UsCultureInfo.DateTimeFormat) + } + + ]; +} \ No newline at end of file diff --git a/src/MockQueryable/MockQueryable.Sample/SampleILikeExpressionVisitor .cs b/src/MockQueryable/MockQueryable.Sample/SampleILikeExpressionVisitor .cs deleted file mode 100644 index 53c2bf7..0000000 --- a/src/MockQueryable/MockQueryable.Sample/SampleILikeExpressionVisitor .cs +++ /dev/null @@ -1,40 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using System; -using System.Linq.Expressions; - -namespace MockQueryable.Sample -{ - public class SampleILikeExpressionVisitor : ExpressionVisitor - { - private static readonly char[] value = ['%']; - - /// - /// Rewrites the ILike method call to a string.Contains call with a trimmed - /// and lowercased pattern. - /// This is used to simulate the behavior of ILike in PostgreSQL, which is - /// case-insensitive and allows for wildcard matching with '%'. - /// - protected override Expression VisitMethodCall(MethodCallExpression node) - { - if (node.Method.Name != nameof(NpgsqlDbFunctionsExtensions.ILike) || - node.Arguments.Count != 3) - { - return base.VisitMethodCall(node); - } - - var stringExpression = node.Arguments[1]; - var patternExpression = node.Arguments[2]; - - var toLowerPattern = Expression.Call(patternExpression, nameof(string.ToLower), Type.EmptyTypes); - var trimMethod = typeof(string).GetMethod(nameof(string.Trim), [typeof(char[])]); - var trimmedPattern = Expression.Call(toLowerPattern, trimMethod!, Expression.Constant(value)); - - return Expression.Call( - Expression.Call(stringExpression, nameof(string.ToLower), Type.EmptyTypes), - nameof(string.Contains), - Type.EmptyTypes, - trimmedPattern - ); - } - } -} diff --git a/src/MockQueryable/MockQueryable.Sample/SampleLikeExpressionVisitor.cs b/src/MockQueryable/MockQueryable.Sample/SampleLikeExpressionVisitor.cs new file mode 100644 index 0000000..87080bc --- /dev/null +++ b/src/MockQueryable/MockQueryable.Sample/SampleLikeExpressionVisitor.cs @@ -0,0 +1,42 @@ +using Microsoft.EntityFrameworkCore; +using System; +using System.Linq.Expressions; + +namespace MockQueryable.Sample; + +/// +/// This class rewrites ILike/Like method calls to simulate EntityFrameworkCore case-insensitive pattern matching in LINQ queries. +/// +public class SampleLikeExpressionVisitor : ExpressionVisitor +{ + private static readonly char[] Value = ['%']; + + /// + /// Rewrites the ILike method call to a string.Contains call with a trimmed + /// and lowercased pattern. + /// This is used to simulate the behavior of ILike/Like + /// + protected override Expression VisitMethodCall(MethodCallExpression node) + { + if (node.Method.Name is nameof(NpgsqlDbFunctionsExtensions.ILike) or nameof(DbFunctionsExtensions.Like) && + node.Arguments.Count == 3) + { + + var stringExpression = node.Arguments[1]; + var patternExpression = node.Arguments[2]; + + var toLowerPattern = Expression.Call(patternExpression, nameof(string.ToLower), Type.EmptyTypes); + var trimMethod = typeof(string).GetMethod(nameof(string.Trim), [typeof(char[])]); + var trimmedPattern = Expression.Call(toLowerPattern, trimMethod!, Expression.Constant(Value)); + + return Expression.Call( + Expression.Call(stringExpression, nameof(string.ToLower), Type.EmptyTypes), + nameof(string.Contains), + Type.EmptyTypes, + trimmedPattern + ); + } + + return base.VisitMethodCall(node); + } +} \ No newline at end of file diff --git a/src/MockQueryable/MockQueryable.Sample/TestDbSetRepository.cs b/src/MockQueryable/MockQueryable.Sample/TestDbSetRepository.cs index db72a66..f1b3223 100644 --- a/src/MockQueryable/MockQueryable.Sample/TestDbSetRepository.cs +++ b/src/MockQueryable/MockQueryable.Sample/TestDbSetRepository.cs @@ -37,8 +37,15 @@ public IAsyncEnumerable GetAllAsync() public async Task> GetUsersByFirstName(string firstName) { return await _dbSet - .Where(x => EF.Functions.ILike(x.FirstName, $"%{firstName}%")) + .Where(x => EF.Functions.Like(x.FirstName, $"%{firstName}%")) .ToListAsync(); } + + public async Task> GetUsersByLastName(string firstName) + { + return await _dbSet + .Where(x => EF.Functions.ILike(x.LastName, $"%{firstName}%")) + .ToListAsync(); + } } } \ No newline at end of file diff --git a/src/MockQueryable/MockQueryable.sln b/src/MockQueryable/MockQueryable.sln index 0c666c1..35c4ff4 100644 --- a/src/MockQueryable/MockQueryable.sln +++ b/src/MockQueryable/MockQueryable.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29102.190 +# Visual Studio Version 17 +VisualStudioVersion = 17.13.35931.197 d17.13 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MockQueryable.Core", "MockQueryable.Core\MockQueryable.Core.csproj", "{7C85327C-5EE5-4C74-A1E5-9B7046CA6CFE}" EndProject @@ -15,6 +15,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MockQueryable.FakeItEasy", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MockQueryable.EntityFrameworkCore", "MockQueryable.EntityFrameworkCore\MockQueryable.EntityFrameworkCore.csproj", "{E3632875-02A1-4C4A-96AB-62089D9D3F4F}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8EC462FD-D22E-90A8-E5CE-7E832BA40C5D}" + ProjectSection(SolutionItems) = preProject + ..\..\.github\workflows\dotnetcore.yml = ..\..\.github\workflows\dotnetcore.yml + ..\..\LICENSE = ..\..\LICENSE + ..\..\README.md = ..\..\README.md + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU From 914e93d1b1fbc99593492d0480c1af53585a0fe7 Mon Sep 17 00:00:00 2001 From: Raman Tsitou Date: Sun, 27 Jul 2025 01:53:25 +0200 Subject: [PATCH 8/8] v8.0.0 --- .../MockQueryable.Core/MockQueryable.Core.csproj | 11 +++++++---- .../MockQueryable.EntityFrameworkCore.csproj | 11 +++++++---- .../MockQueryable.FakeItEasy.csproj | 11 +++++++---- .../MockQueryable.Moq/MockQueryable.Moq.csproj | 11 +++++++---- .../MockQueryable.NSubstitute.csproj | 11 +++++++---- 5 files changed, 35 insertions(+), 20 deletions(-) diff --git a/src/MockQueryable/MockQueryable.Core/MockQueryable.Core.csproj b/src/MockQueryable/MockQueryable.Core/MockQueryable.Core.csproj index cef66c7..2ce3c05 100644 --- a/src/MockQueryable/MockQueryable.Core/MockQueryable.Core.csproj +++ b/src/MockQueryable/MockQueryable.Core/MockQueryable.Core.csproj @@ -14,11 +14,14 @@ Mock EntityFrameworkCore Queryable mock EF UnitTests EntityFrameworkCore true - #81 Add support to ExecuteDelete and ExecuteUpdate - Thanks @lazaro-ansaldi + #81 Add support to ExecuteDelete and ExecuteUpdate - Thanks @lazaro-ansaldi and @Catlandor + #82 Update versions of Moq, NSubstitute and FakeItEasy to newer versions without known vulnerabilities - Thanks @Catlandor + #73 Supporting EF.Functions.Like and/or prossibility to provide cusotm ExpressionVisitor - Thanks @Catlandor + #66 Not suported with EF7: ExecuteDeleteAsync and ExecuteUpdateAsync - Thanks @Catlandor - 7.0.4-beta - 7.0.0.4 - 7.0.0.4 + 8.0.0 + 8.0.0.0 + 8.0.0.0 LICENSE README.md diff --git a/src/MockQueryable/MockQueryable.EntityFrameworkCore/MockQueryable.EntityFrameworkCore.csproj b/src/MockQueryable/MockQueryable.EntityFrameworkCore/MockQueryable.EntityFrameworkCore.csproj index 06fd1ba..9d3b280 100644 --- a/src/MockQueryable/MockQueryable.EntityFrameworkCore/MockQueryable.EntityFrameworkCore.csproj +++ b/src/MockQueryable/MockQueryable.EntityFrameworkCore/MockQueryable.EntityFrameworkCore.csproj @@ -15,11 +15,14 @@ Mock EntityFrameworkCore Queryable mock EF UnitTests EntityFrameworkCore true - #81 Add support to ExecuteDelete and ExecuteUpdate - Thanks @lazaro-ansaldi + #81 Add support to ExecuteDelete and ExecuteUpdate - Thanks @lazaro-ansaldi and @Catlandor + #82 Update versions of Moq, NSubstitute and FakeItEasy to newer versions without known vulnerabilities - Thanks @Catlandor + #73 Supporting EF.Functions.Like and/or prossibility to provide cusotm ExpressionVisitor - Thanks @Catlandor + #66 Not suported with EF7: ExecuteDeleteAsync and ExecuteUpdateAsync - Thanks @Catlandor - 7.0.4-beta - 7.0.0.4 - 7.0.0.4 + 8.0.0 + 8.0.0.0 + 8.0.0.0 LICENSE README.md diff --git a/src/MockQueryable/MockQueryable.FakeItEasy/MockQueryable.FakeItEasy.csproj b/src/MockQueryable/MockQueryable.FakeItEasy/MockQueryable.FakeItEasy.csproj index fe322e8..59b27c9 100644 --- a/src/MockQueryable/MockQueryable.FakeItEasy/MockQueryable.FakeItEasy.csproj +++ b/src/MockQueryable/MockQueryable.FakeItEasy/MockQueryable.FakeItEasy.csproj @@ -14,11 +14,14 @@ Mock EntityFrameworkCore Queryable mock EF EFCore UnitTests FakeItEasy true - #81 Add support to ExecuteDelete and ExecuteUpdate - Thanks @lazaro-ansaldi + #81 Add support to ExecuteDelete and ExecuteUpdate - Thanks @lazaro-ansaldi and @Catlandor + #82 Update versions of Moq, NSubstitute and FakeItEasy to newer versions without known vulnerabilities - Thanks @Catlandor + #73 Supporting EF.Functions.Like and/or prossibility to provide cusotm ExpressionVisitor - Thanks @Catlandor + #66 Not suported with EF7: ExecuteDeleteAsync and ExecuteUpdateAsync - Thanks @Catlandor - 7.0.4-beta - 7.0.0.4 - 7.0.0.4 + 8.0.0 + 8.0.0.0 + 8.0.0.0 LICENSE README.md diff --git a/src/MockQueryable/MockQueryable.Moq/MockQueryable.Moq.csproj b/src/MockQueryable/MockQueryable.Moq/MockQueryable.Moq.csproj index 2ef48d4..3cb09b5 100644 --- a/src/MockQueryable/MockQueryable.Moq/MockQueryable.Moq.csproj +++ b/src/MockQueryable/MockQueryable.Moq/MockQueryable.Moq.csproj @@ -14,11 +14,14 @@ Mock EntityFrameworkCore Queryable mock EF EFCore UnitTests EntityFrameworkCore Moq true - #81 Add support to ExecuteDelete and ExecuteUpdate - Thanks @lazaro-ansaldi + #81 Add support to ExecuteDelete and ExecuteUpdate - Thanks @lazaro-ansaldi and @Catlandor + #82 Update versions of Moq, NSubstitute and FakeItEasy to newer versions without known vulnerabilities - Thanks @Catlandor + #73 Supporting EF.Functions.Like and/or prossibility to provide cusotm ExpressionVisitor - Thanks @Catlandor + #66 Not suported with EF7: ExecuteDeleteAsync and ExecuteUpdateAsync - Thanks @Catlandor - 7.0.4-beta - 7.0.0.4 - 7.0.0.4 + 8.0.0 + 8.0.0.0 + 8.0.0.0 LICENSE README.md diff --git a/src/MockQueryable/MockQueryable.NSubstitute/MockQueryable.NSubstitute.csproj b/src/MockQueryable/MockQueryable.NSubstitute/MockQueryable.NSubstitute.csproj index dfe1ace..5711113 100644 --- a/src/MockQueryable/MockQueryable.NSubstitute/MockQueryable.NSubstitute.csproj +++ b/src/MockQueryable/MockQueryable.NSubstitute/MockQueryable.NSubstitute.csproj @@ -14,11 +14,14 @@ Mock EntityFrameworkCore Queryable mock EF EFCore UnitTests EntityFrameworkCore NSubstitute true - #81 Add support to ExecuteDelete and ExecuteUpdate - Thanks @lazaro-ansaldi + #81 Add support to ExecuteDelete and ExecuteUpdate - Thanks @lazaro-ansaldi and @Catlandor + #82 Update versions of Moq, NSubstitute and FakeItEasy to newer versions without known vulnerabilities - Thanks @Catlandor + #73 Supporting EF.Functions.Like and/or prossibility to provide cusotm ExpressionVisitor - Thanks @Catlandor + #66 Not suported with EF7: ExecuteDeleteAsync and ExecuteUpdateAsync - Thanks @Catlandor - 7.0.4-beta - 7.0.0.4 - 7.0.0.4 + 8.0.0 + 8.0.0.0 + 8.0.0.0 LICENSE README.md