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