1010
1111namespace MockQueryable . FakeItEasy
1212{
13- public static class FakeItEasyExtensions
14- {
15-
16- /// <summary>
17- /// This method allows you to create a mock DbSet for testing purposes.
18- /// It is particularly useful when you want to simulate the behavior of Entity Framework Core's DbSet
19- /// with custom expression handling, such as for testing LINQ queries or database operations.
20- /// The method takes an IQueryable of the entity type and returns a mocked DbSet that implements
21- /// both IAsyncEnumerable and IQueryable interfaces, allowing for asynchronous enumeration
22- /// and LINQ query capabilities.
23- /// </summary>
24- /// <typeparam name="TEntity">
25- /// The type of the entity that the DbSet will represent.
26- /// </typeparam>
27- public static DbSet < TEntity > BuildMockDbSet < TEntity > ( this ICollection < TEntity > data ) where TEntity : class
13+ public static class FakeItEasyExtensions
2814 {
29- return BuildMockDbSet < TEntity , TestExpressionVisitor > ( data ) ;
30- }
3115
32- /// <summary>
33- /// This method allows you to create a mock DbSet for testing purposes.
34- /// It is particularly useful when you want to simulate the behavior of Entity Framework Core's DbSet
35- /// with custom expression handling, such as for testing LINQ queries or database operations.
36- /// The method takes an IQueryable of the entity type and returns a mocked DbSet that implements
37- /// both IAsyncEnumerable and IQueryable interfaces, allowing for asynchronous enumeration
38- /// and LINQ query capabilities.
39- /// </summary>
40- /// <typeparam name="TEntity">
41- /// The type of the entity that the DbSet will represent.
42- /// </typeparam>
43- /// <typeparam name="TExpressionVisitor">
44- /// The type of the expression visitor that will be used to process LINQ expressions.
45- /// Can be used to mock EF Core specific expression handling, such as for ILike expressions.
46- /// </typeparam>
47- public static DbSet < TEntity > BuildMockDbSet < TEntity , TExpressionVisitor > ( this ICollection < TEntity > data )
48- where TEntity : class
49- where TExpressionVisitor : ExpressionVisitor , new ( )
50- {
51- var mock = A . Fake < DbSet < TEntity > > ( d => d . Implements < IAsyncEnumerable < TEntity > > ( ) . Implements < IQueryable < TEntity > > ( ) ) ;
52- var enumerable = new TestAsyncEnumerableEfCore < TEntity , TExpressionVisitor > ( data , entity => data . Remove ( entity ) ) ;
53- mock . ConfigureQueryableCalls ( enumerable , data . AsQueryable ( ) ) ;
54- mock . ConfigureAsyncEnumerableCalls ( enumerable ) ;
55- mock . ConfigureDbSetCalls ( data . AsQueryable ( ) ) ;
16+ /// <summary>
17+ /// This method allows you to create a mock DbSet for testing purposes.
18+ /// It is particularly useful when you want to simulate the behavior of Entity Framework Core's DbSet
19+ /// with custom expression handling, such as for testing LINQ queries or database operations.
20+ /// The method takes an IQueryable of the entity type and returns a mocked DbSet that implements
21+ /// both IAsyncEnumerable and IQueryable interfaces, allowing for asynchronous enumeration
22+ /// and LINQ query capabilities.
23+ /// </summary>
24+ /// <typeparam name="TEntity">
25+ /// The type of the entity that the DbSet will represent.
26+ /// </typeparam>
27+ public static DbSet < TEntity > BuildMockDbSet < TEntity > ( this ICollection < TEntity > data ) where TEntity : class
28+ {
29+ return BuildMockDbSet < TEntity , TestExpressionVisitor > ( data ) ;
30+ }
5631
57- if ( mock is IAsyncEnumerable < TEntity > asyncEnumerable )
58- {
59- A . CallTo ( ( ) => asyncEnumerable . GetAsyncEnumerator ( A < CancellationToken > . Ignored ) ) . ReturnsLazily ( ( ) => enumerable . GetAsyncEnumerator ( ) ) ;
60- }
32+ /// <summary>
33+ /// This method allows you to create a mock DbSet for testing purposes.
34+ /// It is particularly useful when you want to simulate the behavior of Entity Framework Core's DbSet
35+ /// with custom expression handling, such as for testing LINQ queries or database operations.
36+ /// The method takes an IQueryable of the entity type and returns a mocked DbSet that implements
37+ /// both IAsyncEnumerable and IQueryable interfaces, allowing for asynchronous enumeration
38+ /// and LINQ query capabilities.
39+ /// </summary>
40+ /// <typeparam name="TEntity">
41+ /// The type of the entity that the DbSet will represent.
42+ /// </typeparam>
43+ /// <typeparam name="TExpressionVisitor">
44+ /// The type of the expression visitor that will be used to process LINQ expressions.
45+ /// Can be used to mock EF Core specific expression handling, such as for ILike expressions.
46+ /// </typeparam>
47+ public static DbSet < TEntity > BuildMockDbSet < TEntity , TExpressionVisitor > ( this ICollection < TEntity > data )
48+ where TEntity : class
49+ where TExpressionVisitor : ExpressionVisitor , new ( )
50+ {
51+ var mock = A . Fake < DbSet < TEntity > > ( d => d . Implements < IAsyncEnumerable < TEntity > > ( ) . Implements < IQueryable < TEntity > > ( ) ) ;
52+ var enumerable = new TestAsyncEnumerableEfCore < TEntity , TExpressionVisitor > ( data , entity => data . Remove ( entity ) ) ;
53+ mock . ConfigureQueryableCalls ( enumerable , data . AsQueryable ( ) ) ;
54+ mock . ConfigureAsyncEnumerableCalls ( enumerable ) ;
55+ mock . ConfigureDbSetCalls ( data . AsQueryable ( ) ) ;
6156
62- return mock ;
63- }
57+ if ( mock is IAsyncEnumerable < TEntity > asyncEnumerable )
58+ {
59+ A . CallTo ( ( ) => asyncEnumerable . GetAsyncEnumerator ( A < CancellationToken > . Ignored ) ) . ReturnsLazily ( ( ) => enumerable . GetAsyncEnumerator ( ) ) ;
60+ }
6461
65- private static void ConfigureQueryableCalls < TEntity > (
66- this IQueryable < TEntity > mock ,
67- IQueryProvider queryProvider ,
68- IQueryable < TEntity > data ) where TEntity : class
69- {
70- A . CallTo ( ( ) => mock . Provider ) . Returns ( queryProvider ) ;
71- A . CallTo ( ( ) => mock . Expression ) . Returns ( data ? . Expression ) ;
72- A . CallTo ( ( ) => mock . ElementType ) . Returns ( data ? . ElementType ) ;
73- A . CallTo ( ( ) => mock . GetEnumerator ( ) ) . ReturnsLazily ( ( ) => data ? . GetEnumerator ( ) ) ;
74- }
62+ return mock ;
63+ }
7564
76- private static void ConfigureAsyncEnumerableCalls < TEntity > (
77- this DbSet < TEntity > mock ,
78- IAsyncEnumerable < TEntity > enumerable ) where TEntity : class
79- {
80- A . CallTo ( ( ) => mock . GetAsyncEnumerator ( A < CancellationToken > . Ignored ) )
81- . Returns ( enumerable . GetAsyncEnumerator ( ) ) ;
82- }
65+ private static void ConfigureQueryableCalls < TEntity > (
66+ this IQueryable < TEntity > mock ,
67+ IQueryProvider queryProvider ,
68+ IQueryable < TEntity > data ) where TEntity : class
69+ {
70+ A . CallTo ( ( ) => mock . Provider ) . Returns ( queryProvider ) ;
71+ A . CallTo ( ( ) => mock . Expression ) . Returns ( data ? . Expression ) ;
72+ A . CallTo ( ( ) => mock . ElementType ) . Returns ( data ? . ElementType ) ;
73+ A . CallTo ( ( ) => mock . GetEnumerator ( ) ) . ReturnsLazily ( ( ) => data ? . GetEnumerator ( ) ) ;
74+ }
8375
84- private static void ConfigureDbSetCalls < TEntity > ( this DbSet < TEntity > mock , IQueryable < TEntity > data )
85- where TEntity : class
86- {
87- A . CallTo ( ( ) => mock . AsQueryable ( ) ) . Returns ( data . AsQueryable ( ) ) ;
88- A . CallTo ( ( ) => mock . AsAsyncEnumerable ( ) ) . ReturnsLazily ( args => CreateAsyncMock ( data ) ) ;
89- }
76+ private static void ConfigureAsyncEnumerableCalls < TEntity > (
77+ this DbSet < TEntity > mock ,
78+ IAsyncEnumerable < TEntity > enumerable ) where TEntity : class
79+ {
80+ A . CallTo ( ( ) => mock . GetAsyncEnumerator ( A < CancellationToken > . Ignored ) )
81+ . Returns ( enumerable . GetAsyncEnumerator ( ) ) ;
82+ }
9083
91- private static async IAsyncEnumerable < TEntity > CreateAsyncMock < TEntity > (
92- this IEnumerable < TEntity > data )
93- where TEntity : class
94- {
84+ private static void ConfigureDbSetCalls < TEntity > ( this DbSet < TEntity > mock , IQueryable < TEntity > data )
85+ where TEntity : class
86+ {
87+ A . CallTo ( ( ) => mock . AsQueryable ( ) ) . Returns ( mock ) ;
88+ A . CallTo ( ( ) => mock . AsAsyncEnumerable ( ) ) . ReturnsLazily ( args => CreateAsyncMock ( data ) ) ;
89+ }
90+
91+ private static async IAsyncEnumerable < TEntity > CreateAsyncMock < TEntity > (
92+ this IEnumerable < TEntity > data )
93+ where TEntity : class
94+ {
9595
96- foreach ( var entity in data )
97- {
98- yield return entity ;
99- }
96+ foreach ( var entity in data )
97+ {
98+ yield return entity ;
99+ }
100100
101- await Task . CompletedTask ;
101+ await Task . CompletedTask ;
102+ }
102103 }
103- }
104104}
0 commit comments