Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 80 additions & 80 deletions src/MockQueryable/MockQueryable.FakeItEasy/FakeItEasyExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,95 +10,95 @@

namespace MockQueryable.FakeItEasy
{
public static class FakeItEasyExtensions
{

/// <summary>
/// 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.
/// </summary>
/// <typeparam name="TEntity">
/// The type of the entity that the DbSet will represent.
/// </typeparam>
public static DbSet<TEntity> BuildMockDbSet<TEntity>(this ICollection<TEntity> data) where TEntity : class
public static class FakeItEasyExtensions
{
return BuildMockDbSet<TEntity, TestExpressionVisitor>(data);
}

/// <summary>
/// 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.
/// </summary>
/// <typeparam name="TEntity">
/// The type of the entity that the DbSet will represent.
/// </typeparam>
/// <typeparam name="TExpressionVisitor">
/// 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.
/// </typeparam>
public static DbSet<TEntity> BuildMockDbSet<TEntity, TExpressionVisitor>(this ICollection<TEntity> data)
where TEntity : class
where TExpressionVisitor : ExpressionVisitor, new()
{
var mock = A.Fake<DbSet<TEntity>>(d => d.Implements<IAsyncEnumerable<TEntity>>().Implements<IQueryable<TEntity>>());
var enumerable = new TestAsyncEnumerableEfCore<TEntity, TExpressionVisitor>(data, entity => data.Remove(entity));
mock.ConfigureQueryableCalls(enumerable, data.AsQueryable());
mock.ConfigureAsyncEnumerableCalls(enumerable);
mock.ConfigureDbSetCalls(data.AsQueryable());
/// <summary>
/// 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.
/// </summary>
/// <typeparam name="TEntity">
/// The type of the entity that the DbSet will represent.
/// </typeparam>
public static DbSet<TEntity> BuildMockDbSet<TEntity>(this ICollection<TEntity> data) where TEntity : class
{
return BuildMockDbSet<TEntity, TestExpressionVisitor>(data);
}

if (mock is IAsyncEnumerable<TEntity> asyncEnumerable)
{
A.CallTo(() => asyncEnumerable.GetAsyncEnumerator(A<CancellationToken>.Ignored)).ReturnsLazily(() => enumerable.GetAsyncEnumerator());
}
/// <summary>
/// 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.
/// </summary>
/// <typeparam name="TEntity">
/// The type of the entity that the DbSet will represent.
/// </typeparam>
/// <typeparam name="TExpressionVisitor">
/// 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.
/// </typeparam>
public static DbSet<TEntity> BuildMockDbSet<TEntity, TExpressionVisitor>(this ICollection<TEntity> data)
where TEntity : class
where TExpressionVisitor : ExpressionVisitor, new()
{
var mock = A.Fake<DbSet<TEntity>>(d => d.Implements<IAsyncEnumerable<TEntity>>().Implements<IQueryable<TEntity>>());
var enumerable = new TestAsyncEnumerableEfCore<TEntity, TExpressionVisitor>(data, entity => data.Remove(entity));
mock.ConfigureQueryableCalls(enumerable, data.AsQueryable());
mock.ConfigureAsyncEnumerableCalls(enumerable);
mock.ConfigureDbSetCalls(data.AsQueryable());

return mock;
}
if (mock is IAsyncEnumerable<TEntity> asyncEnumerable)
{
A.CallTo(() => asyncEnumerable.GetAsyncEnumerator(A<CancellationToken>.Ignored)).ReturnsLazily(() => enumerable.GetAsyncEnumerator());
}

private static void ConfigureQueryableCalls<TEntity>(
this IQueryable<TEntity> mock,
IQueryProvider queryProvider,
IQueryable<TEntity> 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<TEntity>(
this DbSet<TEntity> mock,
IAsyncEnumerable<TEntity> enumerable) where TEntity : class
{
A.CallTo(() => mock.GetAsyncEnumerator(A<CancellationToken>.Ignored))
.Returns(enumerable.GetAsyncEnumerator());
}
private static void ConfigureQueryableCalls<TEntity>(
this IQueryable<TEntity> mock,
IQueryProvider queryProvider,
IQueryable<TEntity> 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<TEntity>(this DbSet<TEntity> mock, IQueryable<TEntity> data)
where TEntity : class
{
A.CallTo(() => mock.AsQueryable()).Returns(data.AsQueryable());
A.CallTo(() => mock.AsAsyncEnumerable()).ReturnsLazily(args => CreateAsyncMock(data));
}
private static void ConfigureAsyncEnumerableCalls<TEntity>(
this DbSet<TEntity> mock,
IAsyncEnumerable<TEntity> enumerable) where TEntity : class
{
A.CallTo(() => mock.GetAsyncEnumerator(A<CancellationToken>.Ignored))
.Returns(enumerable.GetAsyncEnumerator());
}

private static async IAsyncEnumerable<TEntity> CreateAsyncMock<TEntity>(
this IEnumerable<TEntity> data)
where TEntity : class
{
private static void ConfigureDbSetCalls<TEntity>(this DbSet<TEntity> mock, IQueryable<TEntity> data)
where TEntity : class
{
A.CallTo(() => mock.AsQueryable()).Returns(mock);
A.CallTo(() => mock.AsAsyncEnumerable()).ReturnsLazily(args => CreateAsyncMock(data));
}

private static async IAsyncEnumerable<TEntity> CreateAsyncMock<TEntity>(
this IEnumerable<TEntity> data)
where TEntity : class
{

foreach (var entity in data)
{
yield return entity;
}
foreach (var entity in data)
{
yield return entity;
}

await Task.CompletedTask;
await Task.CompletedTask;
}
}
}
}
154 changes: 76 additions & 78 deletions src/MockQueryable/MockQueryable.Moq/MoqExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,92 +10,90 @@

namespace MockQueryable.Moq
{
public static class MoqExtensions
{

/// <summary>
/// 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.
/// </summary>
/// <typeparam name="TEntity">
/// The type of the entity that the DbSet will represent.
/// </typeparam>
public static Mock<DbSet<TEntity>> BuildMockDbSet<TEntity>(this ICollection<TEntity> data) where TEntity : class
public static class MoqExtensions
{
return BuildMockDbSet<TEntity, TestExpressionVisitor>(data);
}

/// <summary>
/// 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.
/// </summary>
/// <typeparam name="TEntity">
/// The type of the entity that the DbSet will represent.
/// </typeparam>
/// <typeparam name="TExpressionVisitor">
/// 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.
/// </typeparam>
public static Mock<DbSet<TEntity>> BuildMockDbSet<TEntity, TExpressionVisitor>(this ICollection<TEntity> data)
where TEntity : class
where TExpressionVisitor : ExpressionVisitor, new()
{
var mock = new Mock<DbSet<TEntity>>();
var enumerable = new TestAsyncEnumerableEfCore<TEntity, TExpressionVisitor>(data, entity => data.Remove(entity));
mock.ConfigureAsyncEnumerableCalls(enumerable);
mock.As<IQueryable<TEntity>>().ConfigureQueryableCalls(enumerable, data.AsQueryable());
mock.As<IAsyncEnumerable<TEntity>>().Setup(x => x.GetAsyncEnumerator(It.IsAny<CancellationToken>())).Returns(() => enumerable.GetAsyncEnumerator());
mock.Setup(m => m.AsQueryable()).Returns(enumerable);
/// <summary>
/// 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.
/// </summary>
/// <typeparam name="TEntity">
/// The type of the entity that the DbSet will represent.
/// </typeparam>
public static Mock<DbSet<TEntity>> BuildMockDbSet<TEntity>(this ICollection<TEntity> data) where TEntity : class
{
return BuildMockDbSet<TEntity, TestExpressionVisitor>(data);
}

mock.ConfigureDbSetCalls(data.AsQueryable());
return mock;
}
/// <summary>
/// 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.
/// </summary>
/// <typeparam name="TEntity">
/// The type of the entity that the DbSet will represent.
/// </typeparam>
/// <typeparam name="TExpressionVisitor">
/// 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.
/// </typeparam>
public static Mock<DbSet<TEntity>> BuildMockDbSet<TEntity, TExpressionVisitor>(this ICollection<TEntity> data)
where TEntity : class
where TExpressionVisitor : ExpressionVisitor, new()
{
var mock = new Mock<DbSet<TEntity>>();
var enumerable = new TestAsyncEnumerableEfCore<TEntity, TExpressionVisitor>(data, entity => data.Remove(entity));
mock.ConfigureAsyncEnumerableCalls(enumerable);
mock.As<IQueryable<TEntity>>().ConfigureQueryableCalls(enumerable, data.AsQueryable());
mock.As<IAsyncEnumerable<TEntity>>().Setup(x => x.GetAsyncEnumerator(It.IsAny<CancellationToken>())).Returns(() => enumerable.GetAsyncEnumerator());
mock.Setup(m => m.AsQueryable()).Returns(enumerable);

private static void ConfigureDbSetCalls<TEntity>(this Mock<DbSet<TEntity>> mock, IQueryable<TEntity> data)
where TEntity : class
{
mock.Setup(m => m.AsQueryable()).Returns(mock.Object);
mock.Setup(m => m.AsAsyncEnumerable()).Returns(CreateAsyncMock(data));
}
mock.ConfigureDbSetCalls(data.AsQueryable());
return mock;
}

private static void ConfigureQueryableCalls<TEntity>(
this Mock<IQueryable<TEntity>> mock,
IQueryProvider queryProvider,
IQueryable<TEntity> 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 ConfigureDbSetCalls<TEntity>(this Mock<DbSet<TEntity>> mock, IQueryable<TEntity> data)
where TEntity : class
{
mock.Setup(m => m.AsQueryable()).Returns(mock.Object);
mock.Setup(m => m.AsAsyncEnumerable()).Returns(CreateAsyncMock(data));
}

}
private static void ConfigureQueryableCalls<TEntity>(
this Mock<IQueryable<TEntity>> mock,
IQueryProvider queryProvider,
IQueryable<TEntity> 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<TEntity>(
this Mock<DbSet<TEntity>> mock,
IAsyncEnumerable<TEntity> enumerable) where TEntity : class
{
mock.Setup(d => d.GetAsyncEnumerator(It.IsAny<CancellationToken>()))
.Returns(() => enumerable.GetAsyncEnumerator());

}
private static void ConfigureAsyncEnumerableCalls<TEntity>(
this Mock<DbSet<TEntity>> mock,
IAsyncEnumerable<TEntity> enumerable) where TEntity : class
{
mock.Setup(d => d.GetAsyncEnumerator(It.IsAny<CancellationToken>()))
.Returns(() => enumerable.GetAsyncEnumerator());
}

private static async IAsyncEnumerable<TEntity> CreateAsyncMock<TEntity>(IEnumerable<TEntity> data)
where TEntity : class
{
foreach (var entity in data)
{
yield return entity;
}
private static async IAsyncEnumerable<TEntity> CreateAsyncMock<TEntity>(IEnumerable<TEntity> data)
where TEntity : class
{
foreach (var entity in data)
{
yield return entity;
}

await Task.CompletedTask;
await Task.CompletedTask;
}
}
}
}
Loading