├── .github ├── FUNDING.yml └── workflows │ └── dotnetcore.yml ├── .gitignore ├── .travis.yml ├── LICENSE ├── PULL_REQUEST_TEMPLATE.md ├── README.md └── src └── MockQueryable ├── Assets ├── logo-github.png └── logo.png ├── MockQueryable.Core ├── Assets │ └── logo.png ├── MockQueryable.Core.csproj ├── TestExpressionVisitor.cs └── TestQueryProvider.cs ├── MockQueryable.EntityFrameworkCore ├── Assets │ └── logo.png ├── MockQueryable.EntityFrameworkCore.csproj ├── MockQueryableExtensions.cs ├── TestAsyncEnumerator.cs └── TestQueryProviderEfCore.cs ├── MockQueryable.FakeItEasy ├── Assets │ └── logo.png ├── FakeItEasyExtensions.cs └── MockQueryable.FakeItEasy.csproj ├── MockQueryable.Moq ├── Assets │ └── logo.png ├── MockQueryable.Moq.csproj └── MoqExtensions.cs ├── MockQueryable.NSubstitute ├── Assets │ └── logo.png ├── MockQueryable.NSubstitute.csproj └── NSubstituteExtensions.cs ├── MockQueryable.Sample ├── MockQueryable.Sample.csproj ├── MyService.cs ├── MyServiceFakeItEasyTests.cs ├── MyServiceMoqTests.cs ├── MyServiceNSubstituteTests.cs ├── TestDbSetRepository.cs └── TestsSetup.cs └── MockQueryable.sln /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [romantitov] 4 | -------------------------------------------------------------------------------- /.github/workflows/dotnetcore.yml: -------------------------------------------------------------------------------- 1 | name: .NET Core 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v1 12 | - name: Setup .NET Core 13 | uses: actions/setup-dotnet@v1 14 | with: 15 | dotnet-version: '6.0.x' 16 | 17 | - name: Build with dotnet 18 | run: dotnet build src/MockQueryable/*.sln --configuration Release 19 | - name: Test with dotnet 20 | run: dotnet test src/MockQueryable/*.sln 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | # Build results (asp core 1.1) 27 | [Dd]ebug/netcoreapp1.1/ 28 | [Dd]ebugPublic/netcoreapp1.1/ 29 | [Rr]elease/netcoreapp1.1/ 30 | [Rr]eleases/netcoreapp1.1/ 31 | x64/netcoreapp1.1/ 32 | x86/netcoreapp1.1/ 33 | bld/netcoreapp1.1/ 34 | [Bb]in/netcoreapp1.1/ 35 | [Oo]bj/netcoreapp1.1/ 36 | [Ll]og/netcoreapp1.1/ 37 | 38 | # Visual Studio 2015 cache/options directory 39 | .vs/ 40 | # Uncomment if you have tasks that create the project's static files in wwwroot 41 | #wwwroot/ 42 | 43 | # MSTest test Results 44 | [Tt]est[Rr]esult*/ 45 | [Bb]uild[Ll]og.* 46 | 47 | # NUNIT 48 | *.VisualState.xml 49 | TestResult.xml 50 | 51 | # Build Results of an ATL Project 52 | [Dd]ebugPS/ 53 | [Rr]eleasePS/ 54 | dlldata.c 55 | 56 | # .NET Core 57 | project.lock.json 58 | project.fragment.lock.json 59 | artifacts/ 60 | **/Properties/launchSettings.json 61 | 62 | *_i.c 63 | *_p.c 64 | *_i.h 65 | *.ilk 66 | *.meta 67 | *.obj 68 | *.pch 69 | *.pdb 70 | *.pgc 71 | *.pgd 72 | *.rsp 73 | *.sbr 74 | *.tlb 75 | *.tli 76 | *.tlh 77 | *.tmp 78 | *.tmp_proj 79 | *.log 80 | *.vspscc 81 | *.vssscc 82 | .builds 83 | *.pidb 84 | *.svclog 85 | *.scc 86 | 87 | # Chutzpah Test files 88 | _Chutzpah* 89 | 90 | # Visual C++ cache files 91 | ipch/ 92 | *.aps 93 | *.ncb 94 | *.opendb 95 | *.opensdf 96 | *.sdf 97 | *.cachefile 98 | *.VC.db 99 | *.VC.VC.opendb 100 | 101 | # Visual Studio profiler 102 | *.psess 103 | *.vsp 104 | *.vspx 105 | *.sap 106 | 107 | # TFS 2012 Local Workspace 108 | $tf/ 109 | 110 | # Guidance Automation Toolkit 111 | *.gpState 112 | 113 | # ReSharper is a .NET coding add-in 114 | _ReSharper*/ 115 | *.[Rr]e[Ss]harper 116 | *.DotSettings.user 117 | 118 | # JustCode is a .NET coding add-in 119 | .JustCode 120 | 121 | # TeamCity is a build add-in 122 | _TeamCity* 123 | 124 | # DotCover is a Code Coverage Tool 125 | *.dotCover 126 | 127 | # Visual Studio code coverage results 128 | *.coverage 129 | *.coveragexml 130 | 131 | # NCrunch 132 | _NCrunch_* 133 | .*crunch*.local.xml 134 | nCrunchTemp_* 135 | 136 | # MightyMoose 137 | *.mm.* 138 | AutoTest.Net/ 139 | 140 | # Web workbench (sass) 141 | .sass-cache/ 142 | 143 | # Installshield output folder 144 | [Ee]xpress/ 145 | 146 | # DocProject is a documentation generator add-in 147 | DocProject/buildhelp/ 148 | DocProject/Help/*.HxT 149 | DocProject/Help/*.HxC 150 | DocProject/Help/*.hhc 151 | DocProject/Help/*.hhk 152 | DocProject/Help/*.hhp 153 | DocProject/Help/Html2 154 | DocProject/Help/html 155 | 156 | # Click-Once directory 157 | publish/ 158 | 159 | # Publish Web Output 160 | *.[Pp]ublish.xml 161 | *.azurePubxml 162 | # TODO: Comment the next line if you want to checkin your web deploy settings 163 | # but database connection strings (with potential passwords) will be unencrypted 164 | *.pubxml 165 | *.publishproj 166 | 167 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 168 | # checkin your Azure Web App publish settings, but sensitive information contained 169 | # in these scripts will be unencrypted 170 | PublishScripts/ 171 | 172 | # NuGet Packages 173 | *.nupkg 174 | # The packages folder can be ignored because of Package Restore 175 | **/packages/* 176 | # except build/, which is used as an MSBuild target. 177 | !**/packages/build/ 178 | # Uncomment if necessary however generally it will be regenerated when needed 179 | #!**/packages/repositories.config 180 | # NuGet v3's project.json files produces more ignorable files 181 | *.nuget.props 182 | *.nuget.targets 183 | 184 | # Microsoft Azure Build Output 185 | csx/ 186 | *.build.csdef 187 | 188 | # Microsoft Azure Emulator 189 | ecf/ 190 | rcf/ 191 | 192 | # Windows Store app package directories and files 193 | AppPackages/ 194 | BundleArtifacts/ 195 | Package.StoreAssociation.xml 196 | _pkginfo.txt 197 | *.appx 198 | 199 | # Visual Studio cache files 200 | # files ending in .cache can be ignored 201 | *.[Cc]ache 202 | # but keep track of directories ending in .cache 203 | !*.[Cc]ache/ 204 | 205 | # Others 206 | ClientBin/ 207 | ~$* 208 | *~ 209 | *.dbmdl 210 | *.dbproj.schemaview 211 | *.jfm 212 | *.pfx 213 | *.publishsettings 214 | orleans.codegen.cs 215 | 216 | # Since there are multiple workflows, uncomment next line to ignore bower_components 217 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 218 | #bower_components/ 219 | 220 | # RIA/Silverlight projects 221 | Generated_Code/ 222 | 223 | # Backup & report files from converting an old project file 224 | # to a newer Visual Studio version. Backup files are not needed, 225 | # because we have git ;-) 226 | _UpgradeReport_Files/ 227 | Backup*/ 228 | UpgradeLog*.XML 229 | UpgradeLog*.htm 230 | 231 | # SQL Server files 232 | *.mdf 233 | *.ldf 234 | *.ndf 235 | 236 | # Business Intelligence projects 237 | *.rdl.data 238 | *.bim.layout 239 | *.bim_*.settings 240 | 241 | # Microsoft Fakes 242 | FakesAssemblies/ 243 | 244 | # GhostDoc plugin setting file 245 | *.GhostDoc.xml 246 | 247 | # Node.js Tools for Visual Studio 248 | .ntvs_analysis.dat 249 | node_modules/ 250 | 251 | # Typescript v1 declaration files 252 | typings/ 253 | 254 | # Visual Studio 6 build log 255 | *.plg 256 | 257 | # Visual Studio 6 workspace options file 258 | *.opt 259 | 260 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 261 | *.vbw 262 | 263 | # Visual Studio LightSwitch build output 264 | **/*.HTMLClient/GeneratedArtifacts 265 | **/*.DesktopClient/GeneratedArtifacts 266 | **/*.DesktopClient/ModelManifest.xml 267 | **/*.Server/GeneratedArtifacts 268 | **/*.Server/ModelManifest.xml 269 | _Pvt_Extensions 270 | 271 | # Paket dependency manager 272 | .paket/paket.exe 273 | paket-files/ 274 | 275 | # FAKE - F# Make 276 | .fake/ 277 | 278 | # JetBrains Rider 279 | .idea/ 280 | *.sln.iml 281 | 282 | # CodeRush 283 | .cr/ 284 | 285 | # Python Tools for Visual Studio (PTVS) 286 | __pycache__/ 287 | *.pyc 288 | 289 | # Cake - Uncomment if you are using it 290 | # tools/** 291 | # !tools/packages.config 292 | 293 | # Telerik's JustMock configuration file 294 | *.jmconfig 295 | 296 | # BizTalk build output 297 | *.btp.cs 298 | *.btm.cs 299 | *.odx.cs 300 | *.xsd.cs 301 | # ========================= 302 | # Windows detritus 303 | # ========================= 304 | 305 | # Windows image file caches 306 | Thumbs.db 307 | ehthumbs.db 308 | 309 | # Folder config file 310 | Desktop.ini 311 | 312 | # Recycle Bin used on file shares 313 | $RECYCLE.BIN/ 314 | 315 | # Mac desktop service store files 316 | .DS_Store 317 | 318 | # SASS Compiler cache 319 | .sass-cache 320 | 321 | # Visual Studio 2014 CTP 322 | **/*.sln.ide 323 | 324 | # Visual Studio temp something 325 | .vs/ -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: csharp 2 | 3 | dotnet: 2.1 4 | 5 | dist: trusty 6 | 7 | solution: ./src/MockQueryable/MockQueryable.sln 8 | 9 | script: 10 | 11 | - cd src/MockQueryable 12 | 13 | - dotnet restore 14 | 15 | - dotnet build --configuration=Release 16 | 17 | - dotnet test ./MockQueryable.Sample/MockQueryable.Sample.csproj 18 | 19 | 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Raman Tsitou 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # PR Details 2 | 3 | 4 | 5 | ## Description 6 | 7 | 8 | 9 | ## Related Issue 10 | 11 | 12 | 13 | 14 | 15 | 16 | ## How Has This Been Tested 17 | 18 | 19 | 20 | 21 | ## Checklist 22 | 23 | 24 | 25 | 26 | - [ ] My code follows the code style of this project. 27 | - [ ] I have added tests to cover my changes. 28 | - [ ] All new and existing tests passed. 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # MockQueryable 3 | 4 | [![Build status](https://github.com/romantitov/MockQueryable/workflows/.NET%20Core/badge.svg)](https://github.com/romantitov/MockQueryable/actions) 5 | [![Build status](https://ci.appveyor.com/api/projects/status/ggdbipcyyfb4av9e?svg=true)](https://ci.appveyor.com/project/handybudget/mockqueryable) 6 | [![Downloads](https://img.shields.io/nuget/dt/MockQueryable.Moq.svg)](https://www.nuget.org/packages/MockQueryable.Moq/) 7 | [![Downloads](https://img.shields.io/nuget/dt/MockQueryable.NSubstitute.svg)](https://www.nuget.org/packages/MockQueryable.NSubstitute/) 8 | [![Downloads](https://img.shields.io/nuget/dt/MockQueryable.FakeItEasy.svg)](https://www.nuget.org/packages/MockQueryable.FakeItEasy/) 9 | [![License](https://img.shields.io/github/license/romantitov/MockQueryable.svg)](https://github.com/romantitov/MockQueryable/blob/master/LICENSE) 10 | 11 | [![Build history](https://buildstats.info/appveyor/chart/handybudget/mockqueryable)](https://ci.appveyor.com/project/handybudget/mockqueryable/history) 12 | 13 | 14 | 15 | Extensions for mocking [Entity Framework Core](https://github.com/aspnet/EntityFrameworkCore/) (EFCore) operations such ToListAsync, FirstOrDefaultAsync etc. by [Moq](https://github.com/moq/moq), [NSubstitute](http://nsubstitute.github.io/) or [FakeItEasy](https://fakeiteasy.github.io/) 16 | When writing tests for your application it is often desirable to avoid hitting the database. The extensions allow you to achieve this by creating a context – with behavior defined by your tests – that makes use of in-memory data. 17 | 18 | ### When should I use it? 19 | 20 | If you have something similar to the following code: 21 | ```csharp 22 | var query = _userRepository.GetQueryable(); 23 | 24 | await query.AnyAsync(x =>...) 25 | await query.FirstOrDefaultAsync(x =>...) 26 | query.CountAsync(x => ...) 27 | query.ToListAsync() 28 | //etc. 29 | ``` 30 | and you want to cover it by unit tests 31 | 32 | ### How do I get started? 33 | 34 | ```csharp 35 | //1 - create a List with test items 36 | var users = new List() 37 | { 38 | new UserEntity{LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012")}, 39 | ... 40 | }; 41 | 42 | //2 - build mock by extension 43 | var mock = users.BuildMock(); 44 | 45 | //3 - setup the mock as Queryable for Moq 46 | _userRepository.Setup(x => x.GetQueryable()).Returns(mock); 47 | 48 | //3 - setup the mock as Queryable for NSubstitute 49 | _userRepository.GetQueryable().Returns(mock); 50 | 51 | //3 - setup the mock as Queryable for FakeItEasy 52 | A.CallTo(() => userRepository.GetQueryable()).Returns(mock); 53 | ``` 54 | 55 | Do you prefer *DbSet*? 56 | 57 | ```csharp 58 | //2 - build mock by extension 59 | var mock = users.AsQueryable().BuildMockDbSet(); 60 | 61 | //3 - setup DbSet for Moq 62 | var userRepository = new TestDbSetRepository(mock.Object); 63 | 64 | //3 - setup DbSet for NSubstitute or FakeItEasy 65 | var userRepository = new TestDbSetRepository(mock); 66 | 67 | //3 - setup the mock as Queryable for FakeItEasy 68 | A.CallTo(() => userRepository.GetQueryable()).Returns(mock); 69 | ``` 70 | ### Can I extend the mock object created by MockQueryable with custom logic? 71 | MockQueryable creates for your tests a mock object based on in-memory data, but you can also add some custome logic to it. 72 | 73 | ``` C# 74 | var userId = Guid.NewGuid(); 75 | var users = new List 76 | { 77 | new UserEntity{Id = userId,LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012")}, 78 | //etc. 79 | }; 80 | var mock = users.AsQueryable().BuildMockDbSet(); 81 | 82 | //Aditional setup for FindAsync 83 | mock.Setup(x => x.FindAsync(userId)).ReturnsAsync((object[] ids) => 84 | { 85 | var id = (Guid)ids[0]; 86 | return users.FirstOrDefault(x => x.Id == id); 87 | }); 88 | var userRepository = new TestDbSetRepository(mock.Object); 89 | 90 | //Execution FindAsync 91 | var user = await ((DbSet) userRepository.GetQueryable()).FindAsync(userId); 92 | ``` 93 | 94 | Check out the [sample project](https://github.com/romantitov/MockQueryable/tree/master/src/MockQueryable/MockQueryable.Sample) 95 | 96 | ### Where can I get it? 97 | 98 | First, [install NuGet](http://docs.nuget.org/docs/start-here/installing-nuget). 99 | 100 | If you are using **Moq** - then, install [MockQueryable.Moq](https://www.nuget.org/packages/MockQueryable.Moq/) from the package manager console: 101 | 102 | ``` 103 | PM> Install-Package MockQueryable.Moq 104 | ``` 105 | 106 | If you are using **NSubstitute** - then, install [MockQueryable.NSubstitute](https://www.nuget.org/packages/MockQueryable.NSubstitute/) from the package manager console: 107 | 108 | ``` 109 | PM> Install-Package MockQueryable.NSubstitute 110 | ``` 111 | 112 | If you are using **FakeItEasy** - then, install [MockQueryable.FakeItEasy](https://www.nuget.org/packages/MockQueryable.FakeItEasy/) from the package manager console: 113 | 114 | ``` 115 | PM> Install-Package MockQueryable.FakeItEasy 116 | ``` 117 | 118 | ### Can I use it with my favorite mock framework? 119 | 120 | You can install [MockQueryable.EntityFrameworkCore](https://www.nuget.org/packages/MockQueryable.EntityFrameworkCore/) from the package manager console: 121 | 122 | ``` 123 | PM> Install-Package MockQueryable.EntityFrameworkCore 124 | ``` 125 | [![Downloads](https://img.shields.io/nuget/dt/MockQueryable.EntityFrameworkCore.svg)](https://www.nuget.org/packages/MockQueryable.EntityFrameworkCore/) 126 | 127 | or even [MockQueryable.Core](https://www.nuget.org/packages/MockQueryable.Core/) 128 | ``` 129 | PM> Install-Package MockQueryable.Core 130 | ``` 131 | [![Downloads](https://img.shields.io/nuget/dt/MockQueryable.Core.svg)](https://www.nuget.org/packages/MockQueryable.Core/) 132 | 133 | 134 | Then [make your own extension](https://github.com/romantitov/MockQueryable/blob/master/src/MockQueryable/MockQueryable.Moq/MoqExtensions.cs) for your favorite mock framework 135 | -------------------------------------------------------------------------------- /src/MockQueryable/Assets/logo-github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/romantitov/MockQueryable/7f02ca95ab9335e474fc7eb6a148a57b710317a4/src/MockQueryable/Assets/logo-github.png -------------------------------------------------------------------------------- /src/MockQueryable/Assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/romantitov/MockQueryable/7f02ca95ab9335e474fc7eb6a148a57b710317a4/src/MockQueryable/Assets/logo.png -------------------------------------------------------------------------------- /src/MockQueryable/MockQueryable.Core/Assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/romantitov/MockQueryable/7f02ca95ab9335e474fc7eb6a148a57b710317a4/src/MockQueryable/MockQueryable.Core/Assets/logo.png -------------------------------------------------------------------------------- /src/MockQueryable/MockQueryable.Core/MockQueryable.Core.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.1 5 | MockQueryable.Core 6 | Roman Titov 7 | 8 | Core package for MockQueryable extensions for mocking operations such ToListAsync, FirstOrDefaultAsync etc. 9 | When writing tests for your application it is often desirable to avoid hitting the database. The extension allows you to achieve this by creating a context – with behavior defined by your tests – that makes use of in-memory data. 10 | 11 | true 12 | https://github.com/romantitov/MockQueryable 13 | https://github.com/romantitov/MockQueryable 14 | Mock EntityFrameworkCore Queryable mock EF UnitTests EntityFrameworkCore 15 | true 16 | 17 | #80 Altered namespace for extension method to revert a breaking change - Thanks @StevePy 18 | 19 | 7.0.3 20 | 7.0.0.3 21 | 7.0.0.3 22 | 23 | LICENSE 24 | README.md 25 | logo.png 26 | 27 | 28 | 29 | 30 | True 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | True 39 | 40 | 41 | 42 | 43 | 44 | True 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /src/MockQueryable/MockQueryable.Core/TestExpressionVisitor.cs: -------------------------------------------------------------------------------- 1 | using System.Linq.Expressions; 2 | 3 | namespace MockQueryable.Core 4 | { 5 | public class TestExpressionVisitor : ExpressionVisitor 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /src/MockQueryable/MockQueryable.Core/TestQueryProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | namespace MockQueryable.Core 8 | { 9 | public abstract class TestQueryProvider : IOrderedQueryable, IQueryProvider 10 | { 11 | private IEnumerable _enumerable; 12 | 13 | protected TestQueryProvider(Expression expression) 14 | { 15 | Expression = expression; 16 | } 17 | 18 | protected TestQueryProvider(IEnumerable enumerable) 19 | { 20 | _enumerable = enumerable; 21 | Expression = enumerable.AsQueryable().Expression; 22 | } 23 | 24 | public IQueryable CreateQuery(Expression expression) 25 | { 26 | if (expression is MethodCallExpression m) 27 | { 28 | var resultType = m.Method.ReturnType; // it should be IQueryable 29 | var tElement = resultType.GetGenericArguments().First(); 30 | return (IQueryable) CreateInstance(tElement, expression); 31 | } 32 | 33 | return CreateQuery(expression); 34 | } 35 | 36 | public IQueryable CreateQuery(Expression expression) 37 | { 38 | return (IQueryable) CreateInstance(typeof(TEntity), expression); 39 | } 40 | 41 | private object CreateInstance(Type tElement, Expression expression) 42 | { 43 | var queryType = GetType().GetGenericTypeDefinition().MakeGenericType(tElement); 44 | return Activator.CreateInstance(queryType, expression); 45 | } 46 | 47 | public object Execute(Expression expression) 48 | { 49 | return CompileExpressionItem(expression); 50 | } 51 | 52 | public TResult Execute(Expression expression) 53 | { 54 | return CompileExpressionItem(expression); 55 | } 56 | 57 | IEnumerator IEnumerable.GetEnumerator() 58 | { 59 | if (_enumerable == null) _enumerable = CompileExpressionItem>(Expression); 60 | return _enumerable.GetEnumerator(); 61 | } 62 | 63 | IEnumerator IEnumerable.GetEnumerator() 64 | { 65 | if (_enumerable == null) _enumerable = CompileExpressionItem>(Expression); 66 | return _enumerable.GetEnumerator(); 67 | } 68 | 69 | public Type ElementType => typeof(T); 70 | 71 | public Expression Expression { get; } 72 | 73 | public IQueryProvider Provider => this; 74 | 75 | private static TResult CompileExpressionItem(Expression expression) 76 | { 77 | var visitor = new TestExpressionVisitor(); 78 | var body = visitor.Visit(expression); 79 | var f = Expression.Lambda>(body ?? throw new InvalidOperationException($"{nameof(body)} is null"), (IEnumerable) null); 80 | return f.Compile()(); 81 | } 82 | } 83 | } -------------------------------------------------------------------------------- /src/MockQueryable/MockQueryable.EntityFrameworkCore/Assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/romantitov/MockQueryable/7f02ca95ab9335e474fc7eb6a148a57b710317a4/src/MockQueryable/MockQueryable.EntityFrameworkCore/Assets/logo.png -------------------------------------------------------------------------------- /src/MockQueryable/MockQueryable.EntityFrameworkCore/MockQueryable.EntityFrameworkCore.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6 5 | MockQueryable.EntityFrameworkCore 6 | Roman Titov 7 | 8 | Extension for mocking Entity Framework Core operations such ToListAsync, FirstOrDefaultAsync etc. 9 | When writing tests for your application it is often desirable to avoid hitting the database. The extension allows you to achieve this by creating a context – with behavior defined by your tests – that makes use of in-memory data. 10 | 11 | true 12 | true 13 | https://github.com/romantitov/MockQueryable 14 | https://github.com/romantitov/MockQueryable 15 | Mock EntityFrameworkCore Queryable mock EF UnitTests EntityFrameworkCore 16 | true 17 | 18 | #80 Altered namespace for extension method to revert a breaking change - Thanks @StevePy 19 | 20 | 7.0.3 21 | 7.0.0.3 22 | 7.0.0.3 23 | 24 | LICENSE 25 | README.md 26 | logo.png 27 | 28 | 29 | 30 | 31 | True 32 | 33 | 34 | 35 | 36 | 37 | True 38 | 39 | 40 | 41 | 42 | 43 | True 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /src/MockQueryable/MockQueryable.EntityFrameworkCore/MockQueryableExtensions.cs: -------------------------------------------------------------------------------- 1 | using MockQueryable.EntityFrameworkCore; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | // Moving MockQueryableExtensions BuildMock into the MockQueryable.EntityFrameworkCore 6 | // namespace had breaking changes with earlier extensions added to MockQueryable.Moq 7 | // and other previous extension method locations. Moving this extension up a namespace to 8 | // MockQueryable aleviates that breaking change. It still needs to remain in EF core since it 9 | // is dependent on the EF Core AsyncEnumerable. 10 | namespace MockQueryable 11 | { 12 | public static class MockQueryableExtensions 13 | { 14 | public static IQueryable BuildMock(this IEnumerable data) where TEntity : class 15 | { 16 | return new TestAsyncEnumerableEfCore(data); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/MockQueryable/MockQueryable.EntityFrameworkCore/TestAsyncEnumerator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | 5 | namespace MockQueryable.EntityFrameworkCore 6 | { 7 | public class TestAsyncEnumerator : IAsyncEnumerator 8 | { 9 | private readonly IEnumerator _enumerator; 10 | 11 | public TestAsyncEnumerator(IEnumerator enumerator) 12 | { 13 | _enumerator = enumerator ?? throw new ArgumentNullException(); 14 | } 15 | 16 | public T Current => _enumerator.Current; 17 | 18 | public ValueTask DisposeAsync() 19 | { 20 | _enumerator.Dispose(); 21 | return new ValueTask(); 22 | } 23 | 24 | public ValueTask MoveNextAsync() 25 | { 26 | return new ValueTask(_enumerator.MoveNext()); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/MockQueryable/MockQueryable.EntityFrameworkCore/TestQueryProviderEfCore.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Linq.Expressions; 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | using Microsoft.EntityFrameworkCore.Query; 7 | using MockQueryable.Core; 8 | 9 | namespace MockQueryable.EntityFrameworkCore 10 | { 11 | public class TestAsyncEnumerableEfCore: TestQueryProvider, IAsyncEnumerable, IAsyncQueryProvider 12 | { 13 | public TestAsyncEnumerableEfCore(Expression expression) : base(expression) 14 | { 15 | } 16 | 17 | public TestAsyncEnumerableEfCore(IEnumerable enumerable) : base(enumerable) 18 | { 19 | } 20 | 21 | public TResult ExecuteAsync(Expression expression, CancellationToken cancellationToken) 22 | { 23 | var expectedResultType = typeof(TResult).GetGenericArguments()[0]; 24 | var executionResult = typeof(IQueryProvider) 25 | .GetMethods() 26 | .First(method => method.Name == nameof(IQueryProvider.Execute) && method.IsGenericMethod) 27 | .MakeGenericMethod(expectedResultType) 28 | .Invoke(this, new object[] { expression }); 29 | 30 | return (TResult)typeof(Task).GetMethod(nameof(Task.FromResult)) 31 | .MakeGenericMethod(expectedResultType) 32 | .Invoke(null, new[] { executionResult }); 33 | } 34 | 35 | public IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) 36 | { 37 | return new TestAsyncEnumerator(this.AsEnumerable().GetEnumerator()); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/MockQueryable/MockQueryable.FakeItEasy/Assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/romantitov/MockQueryable/7f02ca95ab9335e474fc7eb6a148a57b710317a4/src/MockQueryable/MockQueryable.FakeItEasy/Assets/logo.png -------------------------------------------------------------------------------- /src/MockQueryable/MockQueryable.FakeItEasy/FakeItEasyExtensions.cs: -------------------------------------------------------------------------------- 1 | using FakeItEasy; 2 | using Microsoft.EntityFrameworkCore; 3 | using MockQueryable.EntityFrameworkCore; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | 9 | namespace MockQueryable.FakeItEasy 10 | { 11 | public static class FakeItEasyExtensions 12 | { 13 | public static DbSet BuildMockDbSet(this IEnumerable data) where TEntity : class => data.BuildMock().BuildMockDbSet(); 14 | 15 | public static DbSet BuildMockDbSet(this IQueryable data) where TEntity : class 16 | { 17 | var mock = A.Fake>(d => d.Implements>().Implements>()); 18 | var enumerable = new TestAsyncEnumerableEfCore(data); 19 | mock.ConfigureQueryableCalls(enumerable, data); 20 | mock.ConfigureAsyncEnumerableCalls(enumerable); 21 | mock.ConfigureDbSetCalls(data); 22 | if (mock is IAsyncEnumerable asyncEnumerable) 23 | { 24 | A.CallTo(() => asyncEnumerable.GetAsyncEnumerator(A.Ignored)).ReturnsLazily(() => enumerable.GetAsyncEnumerator()); 25 | } 26 | return mock; 27 | } 28 | 29 | 30 | private static void ConfigureQueryableCalls( 31 | this IQueryable mock, 32 | IQueryProvider queryProvider, 33 | IQueryable data) where TEntity : class 34 | { 35 | A.CallTo(() => mock.Provider).Returns(queryProvider); 36 | A.CallTo(() => mock.Expression).Returns(data?.Expression); 37 | A.CallTo(() => mock.ElementType).Returns(data?.ElementType); 38 | A.CallTo(() => mock.GetEnumerator()).ReturnsLazily(() => data?.GetEnumerator()); 39 | } 40 | 41 | private static void ConfigureAsyncEnumerableCalls( 42 | this DbSet mock, 43 | IAsyncEnumerable enumerable) where TEntity : class 44 | { 45 | A.CallTo(() => mock.GetAsyncEnumerator(A.Ignored)) 46 | .Returns(enumerable.GetAsyncEnumerator()); 47 | 48 | } 49 | 50 | private static void ConfigureDbSetCalls(this DbSet mock, IQueryable data) 51 | where TEntity : class 52 | { 53 | A.CallTo(() => mock.AsQueryable()).Returns(data); 54 | A.CallTo(() => mock.AsAsyncEnumerable()).ReturnsLazily(args => CreateAsyncMock(data)); 55 | } 56 | 57 | private static async IAsyncEnumerable CreateAsyncMock(IEnumerable data) 58 | where TEntity : class 59 | { 60 | foreach (var entity in data) 61 | { 62 | yield return entity; 63 | } 64 | 65 | await Task.CompletedTask; 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /src/MockQueryable/MockQueryable.FakeItEasy/MockQueryable.FakeItEasy.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6 5 | MockQueryable.FakeItEasy 6 | Roman Titov 7 | 8 | Extension for mocking Entity Framework Core operations such ToListAsync, FirstOrDefaultAsync etc. 9 | When writing tests for your application it is often desirable to avoid hitting the database. The extension allows you to achieve this by creating a context – with behavior defined by your tests – that makes use of in-memory data. 10 | 11 | true 12 | https://github.com/romantitov/MockQueryable 13 | https://github.com/romantitov/MockQueryable 14 | Mock EntityFrameworkCore Queryable mock EF EFCore UnitTests FakeItEasy 15 | true 16 | 17 | #80 Altered namespace for extension method to revert a breaking change - Thanks @StevePy 18 | 19 | 7.0.3 20 | 7.0.0.3 21 | 7.0.0.3 22 | 23 | LICENSE 24 | README.md 25 | logo.png 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | True 35 | 36 | 37 | 38 | 39 | 40 | True 41 | 42 | 43 | 44 | 45 | 46 | True 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /src/MockQueryable/MockQueryable.Moq/Assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/romantitov/MockQueryable/7f02ca95ab9335e474fc7eb6a148a57b710317a4/src/MockQueryable/MockQueryable.Moq/Assets/logo.png -------------------------------------------------------------------------------- /src/MockQueryable/MockQueryable.Moq/MockQueryable.Moq.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6 5 | MockQueryable.Moq 6 | Roman Titov 7 | 8 | Extension for mocking Entity Framework Core operations such ToListAsync, FirstOrDefaultAsync etc. 9 | When writing tests for your application it is often desirable to avoid hitting the database. The extension allows you to achieve this by creating a context – with behavior defined by your tests – that makes use of in-memory data. 10 | 11 | true 12 | https://github.com/romantitov/MockQueryable 13 | https://github.com/romantitov/MockQueryable 14 | Mock EntityFrameworkCore Queryable mock EF EFCore UnitTests EntityFrameworkCore Moq 15 | true 16 | 17 | #80 Altered namespace for extension method to revert a breaking change - Thanks @StevePy 18 | 19 | 7.0.3 20 | 7.0.0.3 21 | 7.0.0.3 22 | 23 | LICENSE 24 | README.md 25 | logo.png 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | True 36 | 37 | 38 | 39 | 40 | 41 | True 42 | 43 | 44 | 45 | 46 | 47 | True 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /src/MockQueryable/MockQueryable.Moq/MoqExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | using Microsoft.EntityFrameworkCore; 6 | using MockQueryable.EntityFrameworkCore; 7 | using Moq; 8 | 9 | namespace MockQueryable.Moq 10 | { 11 | public static class MoqExtensions 12 | { 13 | 14 | public static Mock> BuildMockDbSet(this IEnumerable data) where TEntity : class => data.BuildMock().BuildMockDbSet(); 15 | 16 | public static Mock> BuildMockDbSet(this IQueryable data) where TEntity : class 17 | { 18 | var mock = new Mock>(); 19 | var enumerable = new TestAsyncEnumerableEfCore(data); 20 | mock.ConfigureAsyncEnumerableCalls(enumerable); 21 | mock.As>().ConfigureQueryableCalls(enumerable, data); 22 | mock.As>().Setup(x => x.GetAsyncEnumerator(It.IsAny())).Returns(() => enumerable.GetAsyncEnumerator()); 23 | mock.Setup(m => m.AsQueryable()).Returns(enumerable); 24 | 25 | mock.ConfigureDbSetCalls(data); 26 | return mock; 27 | } 28 | 29 | private static void ConfigureDbSetCalls(this Mock> mock, IQueryable data) 30 | where TEntity : class 31 | { 32 | mock.Setup(m => m.AsQueryable()).Returns(mock.Object); 33 | mock.Setup(m => m.AsAsyncEnumerable()).Returns(CreateAsyncMock(data)); 34 | } 35 | 36 | private static void ConfigureQueryableCalls( 37 | this Mock> mock, 38 | IQueryProvider queryProvider, 39 | IQueryable data) where TEntity : class 40 | { 41 | mock.Setup(m => m.Provider).Returns(queryProvider); 42 | mock.Setup(m => m.Expression).Returns(data?.Expression); 43 | mock.Setup(m => m.ElementType).Returns(data?.ElementType); 44 | mock.Setup(m => m.GetEnumerator()).Returns(() => data?.GetEnumerator()); 45 | 46 | } 47 | 48 | private static void ConfigureAsyncEnumerableCalls( 49 | this Mock> mock, 50 | IAsyncEnumerable enumerable)where TEntity : class 51 | { 52 | mock.Setup(d => d.GetAsyncEnumerator(It.IsAny())) 53 | .Returns(() => enumerable.GetAsyncEnumerator()); 54 | 55 | } 56 | 57 | private static async IAsyncEnumerable CreateAsyncMock(IEnumerable data) 58 | where TEntity : class 59 | { 60 | foreach (var entity in data) 61 | { 62 | yield return entity; 63 | } 64 | 65 | await Task.CompletedTask; 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /src/MockQueryable/MockQueryable.NSubstitute/Assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/romantitov/MockQueryable/7f02ca95ab9335e474fc7eb6a148a57b710317a4/src/MockQueryable/MockQueryable.NSubstitute/Assets/logo.png -------------------------------------------------------------------------------- /src/MockQueryable/MockQueryable.NSubstitute/MockQueryable.NSubstitute.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6 5 | MockQueryable.NSubstitute 6 | Roman Titov 7 | 8 | Extension for mocking Entity Framework Core operations such ToListAsync, FirstOrDefaultAsync etc. 9 | When writing tests for your application it is often desirable to avoid hitting the database. The extension allows you to achieve this by creating a context – with behavior defined by your tests – that makes use of in-memory data. 10 | 11 | true 12 | https://github.com/romantitov/MockQueryable 13 | https://github.com/romantitov/MockQueryable 14 | Mock EntityFrameworkCore Queryable mock EF EFCore UnitTests EntityFrameworkCore NSubstitute 15 | true 16 | 17 | #80 Altered namespace for extension method to revert a breaking change - Thanks @StevePy 18 | 19 | 7.0.3 20 | 7.0.0.3 21 | 7.0.0.3 22 | 23 | LICENSE 24 | README.md 25 | logo.png 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | True 34 | 35 | 36 | 37 | 38 | 39 | True 40 | 41 | 42 | 43 | 44 | 45 | True 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /src/MockQueryable/MockQueryable.NSubstitute/NSubstituteExtensions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using MockQueryable.EntityFrameworkCore; 3 | using NSubstitute; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | 9 | namespace MockQueryable.NSubstitute 10 | { 11 | public static class NSubstituteExtensions 12 | { 13 | public static DbSet BuildMockDbSet(this IEnumerable data) where TEntity : class => data.BuildMock().BuildMockDbSet(); 14 | 15 | public static DbSet BuildMockDbSet(this IQueryable data) where TEntity : class 16 | { 17 | var mock = Substitute.For, IQueryable, IAsyncEnumerable>(); 18 | var enumerable = new TestAsyncEnumerableEfCore(data); 19 | 20 | mock.ConfigureAsyncEnumerableCalls(enumerable); 21 | mock.ConfigureQueryableCalls(enumerable, data); 22 | mock.ConfigureDbSetCalls(data); 23 | 24 | if (mock is IAsyncEnumerable asyncEnumerable) 25 | { 26 | asyncEnumerable.GetAsyncEnumerator(Arg.Any()).Returns(args => enumerable.GetAsyncEnumerator()); 27 | } 28 | 29 | return mock; 30 | } 31 | 32 | 33 | private static void ConfigureQueryableCalls( 34 | this IQueryable mock, 35 | IQueryProvider queryProvider, 36 | IQueryable data) where TEntity : class 37 | { 38 | mock.Provider.Returns(queryProvider); 39 | mock.Expression.Returns(data?.Expression); 40 | mock.ElementType.Returns(data?.ElementType); 41 | mock.GetEnumerator().Returns(info => data?.GetEnumerator()); 42 | } 43 | 44 | private static void ConfigureAsyncEnumerableCalls( 45 | this DbSet mock, 46 | IAsyncEnumerable enumerable) where TEntity : class 47 | { 48 | mock.GetAsyncEnumerator(Arg.Any()).Returns(args => enumerable.GetAsyncEnumerator()); 49 | } 50 | 51 | private static void ConfigureDbSetCalls(this DbSet mock, IQueryable data) 52 | where TEntity : class 53 | { 54 | mock.AsQueryable().Returns(data); 55 | mock.AsAsyncEnumerable().Returns(args => CreateAsyncMock(data)); 56 | } 57 | 58 | private static async IAsyncEnumerable CreateAsyncMock(IEnumerable data) 59 | where TEntity : class 60 | { 61 | foreach (var entity in data) 62 | { 63 | yield return entity; 64 | } 65 | 66 | await Task.CompletedTask; 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /src/MockQueryable/MockQueryable.Sample/MockQueryable.Sample.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | all 13 | runtime; build; native; contentfiles; analyzers; buildtransitive 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/MockQueryable/MockQueryable.Sample/MyService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using AutoMapper; 6 | using AutoMapper.QueryableExtensions; 7 | using Microsoft.EntityFrameworkCore; 8 | 9 | namespace MockQueryable.Sample 10 | { 11 | public class MyService 12 | { 13 | private readonly IUserRepository _userRepository; 14 | 15 | public static void Initialize() 16 | { 17 | Mapper.Initialize(cfg => cfg.CreateMap() 18 | .ForMember(dto => dto.FirstName, conf => conf.MapFrom(ol => ol.FirstName)) 19 | .ForMember(dto => dto.LastName, conf => conf.MapFrom(ol => ol.LastName))); 20 | Mapper.Configuration.AssertConfigurationIsValid(); 21 | } 22 | 23 | public MyService(IUserRepository userRepository) 24 | { 25 | _userRepository = userRepository; 26 | } 27 | 28 | public async Task CreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth) 29 | { 30 | var query = _userRepository.GetQueryable(); 31 | 32 | if (await query.AnyAsync(x => x.LastName == lastName && x.DateOfBirth == dateOfBirth)) 33 | { 34 | throw new ApplicationException("User already exist"); 35 | } 36 | 37 | var existUser = await query.FirstOrDefaultAsync(x => x.FirstName == firstName); 38 | if (existUser != null) 39 | { 40 | throw new ApplicationException("User with FirstName already exist"); 41 | } 42 | 43 | if (await query.CountAsync(x => x.DateOfBirth == dateOfBirth.Date) > 3) 44 | { 45 | throw new ApplicationException("Users with DateOfBirth more than limit"); 46 | } 47 | 48 | await _userRepository.CreateUser(new UserEntity 49 | { 50 | FirstName = firstName, 51 | LastName = lastName, 52 | DateOfBirth = dateOfBirth.Date, 53 | }); 54 | 55 | } 56 | 57 | public async Task> GetUserReports(DateTime dateFrom, DateTime dateTo) 58 | { 59 | var query = _userRepository.GetQueryable(); 60 | 61 | query = query.Where(x => x.DateOfBirth >= dateFrom.Date); 62 | query = query.Where(x => x.DateOfBirth <= dateTo.Date); 63 | 64 | return await query.Select(x => new UserReport 65 | { 66 | FirstName = x.FirstName, 67 | LastName = x.LastName, 68 | }).ToListAsync(); 69 | } 70 | 71 | 72 | public async Task> GetUserReportsAutoMap(DateTime dateFrom, DateTime dateTo) 73 | { 74 | var query = _userRepository.GetQueryable(); 75 | 76 | query = query.Where(x => x.DateOfBirth >= dateFrom.Date); 77 | query = query.Where(x => x.DateOfBirth <= dateTo.Date); 78 | 79 | return await query.ProjectTo().ToListAsync(); 80 | } 81 | } 82 | 83 | public interface IUserRepository 84 | { 85 | IQueryable GetQueryable(); 86 | 87 | Task CreateUser(UserEntity user); 88 | 89 | Task> GetAll(); 90 | 91 | IAsyncEnumerable GetAllAsync(); 92 | } 93 | 94 | 95 | public class UserReport 96 | { 97 | public string FirstName { get; set; } 98 | public string LastName { get; set; } 99 | } 100 | 101 | public class UserEntity 102 | { 103 | public Guid Id { get; set; } 104 | public string FirstName { get; set; } 105 | public string LastName { get; set; } 106 | public DateTime DateOfBirth { get; set; } 107 | } 108 | } -------------------------------------------------------------------------------- /src/MockQueryable/MockQueryable.Sample/MyServiceFakeItEasyTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Linq; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | using FakeItEasy; 8 | using Microsoft.EntityFrameworkCore; 9 | using MockQueryable.FakeItEasy; 10 | using NUnit.Framework; 11 | 12 | namespace MockQueryable.Sample 13 | { 14 | [TestFixture] 15 | public class MyServiceFakeItEasyTests 16 | { 17 | private static readonly CultureInfo UsCultureInfo = new CultureInfo("en-US"); 18 | 19 | [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] 20 | [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] 21 | [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] 22 | public void CreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) 23 | { 24 | //arrange 25 | 26 | var userRepository = A.Fake(); 27 | var service = new MyService(userRepository); 28 | var users = new List 29 | { 30 | new UserEntity {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, 31 | new UserEntity {FirstName = "ExistFirstName"}, 32 | new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, 33 | new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, 34 | new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, 35 | }; 36 | //expect 37 | var mock = users.BuildMock(); 38 | A.CallTo(() => userRepository.GetQueryable()).Returns(mock); 39 | //act 40 | var ex = Assert.ThrowsAsync(() => 41 | service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); 42 | //assert 43 | Assert.AreEqual(expectedError, ex.Message); 44 | 45 | } 46 | 47 | [TestCase("01/20/2012", "06/20/2018", 5)] 48 | [TestCase("01/20/2012", "06/20/2012", 4)] 49 | [TestCase("01/20/2012", "02/20/2012", 3)] 50 | [TestCase("01/20/2010", "02/20/2011", 0)] 51 | public async Task GetUserReports(DateTime from, DateTime to, int expectedCount) 52 | { 53 | //arrange 54 | var userRepository = A.Fake(); 55 | var service = new MyService(userRepository); 56 | var users = CreateUserList(); 57 | //expect 58 | var mock = users.BuildMock(); 59 | A.CallTo(() => userRepository.GetQueryable()).Returns(mock); 60 | //act 61 | var result = await service.GetUserReports(from, to); 62 | //assert 63 | Assert.AreEqual(expectedCount, result.Count); 64 | 65 | } 66 | 67 | 68 | [TestCase("01/20/2012", "06/20/2018", 5)] 69 | [TestCase("01/20/2012", "06/20/2012", 4)] 70 | [TestCase("01/20/2012", "02/20/2012", 3)] 71 | [TestCase("01/20/2010", "02/20/2011", 0)] 72 | public async Task GetUserReports_AutoMap(DateTime from, DateTime to, int expectedCount) 73 | { 74 | //arrange 75 | var userRepository = A.Fake(); 76 | var service = new MyService(userRepository); 77 | var users = CreateUserList(); 78 | //expect 79 | var mock = users.BuildMock(); 80 | A.CallTo(() => userRepository.GetQueryable()).Returns(mock); 81 | //act 82 | var result = await service.GetUserReportsAutoMap(from, to); 83 | //assert 84 | Assert.AreEqual(expectedCount, result.Count); 85 | 86 | } 87 | 88 | [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] 89 | [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] 90 | [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] 91 | public void DbSetCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) 92 | { 93 | //arrange 94 | var users = new List 95 | { 96 | new UserEntity {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, 97 | new UserEntity {FirstName = "ExistFirstName"}, 98 | new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, 99 | new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, 100 | new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, 101 | }; 102 | var mock = users.AsQueryable().BuildMockDbSet(); 103 | var userRepository = new TestDbSetRepository(mock); 104 | var service = new MyService(userRepository); 105 | //act 106 | var ex = Assert.ThrowsAsync(() => 107 | service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); 108 | //assert 109 | Assert.AreEqual(expectedError, ex.Message); 110 | 111 | } 112 | 113 | [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] 114 | [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] 115 | [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] 116 | public void DbSetCreatedFromCollectionCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) 117 | { 118 | //arrange 119 | var users = new List 120 | { 121 | new UserEntity {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, 122 | new UserEntity {FirstName = "ExistFirstName"}, 123 | new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, 124 | new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, 125 | new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, 126 | }; 127 | var mock = users.BuildMockDbSet(); 128 | var userRepository = new TestDbSetRepository(mock); 129 | var service = new MyService(userRepository); 130 | //act 131 | var ex = Assert.ThrowsAsync(() => 132 | service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); 133 | //assert 134 | Assert.AreEqual(expectedError, ex.Message); 135 | 136 | } 137 | 138 | [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] 139 | public async Task DbSetCreateUser(string firstName, string lastName, DateTime dateOfBirth) 140 | { 141 | //arrange 142 | var userEntities = new List(); 143 | var mock = userEntities.AsQueryable().BuildMockDbSet(); 144 | A.CallTo(() => mock.AddAsync(A._, A._)) 145 | .ReturnsLazily(call => 146 | { 147 | userEntities.Add((UserEntity) call.Arguments[0]); 148 | return default; 149 | }); 150 | var userRepository = new TestDbSetRepository(mock); 151 | var service = new MyService(userRepository); 152 | //act 153 | await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); 154 | // assert 155 | var entity = mock.Single(); 156 | Assert.AreEqual(firstName, entity.FirstName); 157 | Assert.AreEqual(lastName, entity.LastName); 158 | Assert.AreEqual(dateOfBirth, entity.DateOfBirth); 159 | } 160 | 161 | [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] 162 | public async Task DbSetCreatedFromCollectionCreateUser1(string firstName, string lastName, DateTime dateOfBirth) 163 | { 164 | //arrange 165 | var userEntities = new List(); 166 | var mock = userEntities.BuildMockDbSet(); 167 | A.CallTo(() => mock.AddAsync(A._, A._)) 168 | .ReturnsLazily(call => 169 | { 170 | userEntities.Add((UserEntity)call.Arguments[0]); 171 | return default; 172 | }); 173 | var userRepository = new TestDbSetRepository(mock); 174 | var service = new MyService(userRepository); 175 | //act 176 | await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); 177 | // assert 178 | var entity = mock.Single(); 179 | Assert.AreEqual(firstName, entity.FirstName); 180 | Assert.AreEqual(lastName, entity.LastName); 181 | Assert.AreEqual(dateOfBirth, entity.DateOfBirth); 182 | } 183 | 184 | [TestCase("01/20/2012", "06/20/2018", 5)] 185 | [TestCase("01/20/2012", "06/20/2012", 4)] 186 | [TestCase("01/20/2012", "02/20/2012", 3)] 187 | [TestCase("01/20/2010", "02/20/2011", 0)] 188 | public async Task DbSetGetUserReports(DateTime from, DateTime to, int expectedCount) 189 | { 190 | //arrange 191 | var users = CreateUserList(); 192 | var mock = users.AsQueryable().BuildMockDbSet(); 193 | var userRepository = new TestDbSetRepository(mock); 194 | var service = new MyService(userRepository); 195 | //act 196 | var result = await service.GetUserReports(from, to); 197 | //assert 198 | Assert.AreEqual(expectedCount, result.Count); 199 | } 200 | 201 | [TestCase("01/20/2012", "06/20/2018", 5)] 202 | [TestCase("01/20/2012", "06/20/2012", 4)] 203 | [TestCase("01/20/2012", "02/20/2012", 3)] 204 | [TestCase("01/20/2010", "02/20/2011", 0)] 205 | public async Task DbSetCreatedFromCollectionGetUserReports(DateTime from, DateTime to, int expectedCount) 206 | { 207 | //arrange 208 | var users = CreateUserList(); 209 | var mock = users.BuildMockDbSet(); 210 | var userRepository = new TestDbSetRepository(mock); 211 | var service = new MyService(userRepository); 212 | //act 213 | var result = await service.GetUserReports(from, to); 214 | //assert 215 | Assert.AreEqual(expectedCount, result.Count); 216 | } 217 | 218 | [TestCase] 219 | public async Task DbSetGetAllUserEntitiesAsync() 220 | { 221 | // arrange 222 | var users = CreateUserList(); 223 | 224 | var mockDbSet = users.AsQueryable().BuildMockDbSet(); 225 | var userRepository = new TestDbSetRepository(mockDbSet); 226 | 227 | // act 228 | var result = await userRepository.GetAllAsync().ToListAsync(); 229 | 230 | // assert 231 | Assert.AreEqual(users.Count, result.Count); 232 | } 233 | 234 | [TestCase] 235 | public async Task DbSetCreatedFromCollectionGetAllUserEntitiesAsync() 236 | { 237 | // arrange 238 | var users = CreateUserList(); 239 | 240 | var mockDbSet = users.BuildMockDbSet(); 241 | var userRepository = new TestDbSetRepository(mockDbSet); 242 | 243 | // act 244 | var result = await userRepository.GetAllAsync().ToListAsync(); 245 | 246 | // assert 247 | Assert.AreEqual(users.Count, result.Count); 248 | } 249 | 250 | [TestCase] 251 | public async Task DbSetToListAsyncAsync_ShouldReturnAllEntities_WhenSourceIsChanged() 252 | { 253 | // arrange 254 | var users = new List(); 255 | 256 | var mockDbSet = users.AsQueryable().BuildMockDbSet(); 257 | 258 | // act 259 | var result1 = await mockDbSet.ToListAsync(); 260 | users.AddRange(CreateUserList()); 261 | var result2 = await mockDbSet.ToListAsync(); 262 | 263 | // assert 264 | Assert.AreEqual(0, result1.Count); 265 | Assert.AreEqual(users.Count, result2.Count); 266 | } 267 | 268 | [TestCase] 269 | public async Task DbSetGetAllUserEntity() 270 | { 271 | //arrange 272 | var users = CreateUserList(); 273 | var mock = users.AsQueryable().BuildMockDbSet(); 274 | var userRepository = new TestDbSetRepository(mock); 275 | //act 276 | var result = await userRepository.GetAll(); 277 | //assert 278 | Assert.AreEqual(users.Count, result.Count); 279 | } 280 | 281 | [TestCase] 282 | public async Task DbSetCreatedFromCollectionGetAllUserEntity() 283 | { 284 | //arrange 285 | var users = CreateUserList(); 286 | var mock = users.BuildMockDbSet(); 287 | var userRepository = new TestDbSetRepository(mock); 288 | //act 289 | var result = await userRepository.GetAll(); 290 | //assert 291 | Assert.AreEqual(users.Count, result.Count); 292 | } 293 | 294 | private static List CreateUserList() => new List 295 | { 296 | new UserEntity 297 | { 298 | FirstName = "FirstName1", LastName = "LastName", 299 | DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) 300 | }, 301 | new UserEntity 302 | { 303 | FirstName = "FirstName2", LastName = "LastName", 304 | DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) 305 | }, 306 | new UserEntity 307 | { 308 | FirstName = "FirstName3", LastName = "LastName", 309 | DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) 310 | }, 311 | new UserEntity 312 | { 313 | FirstName = "FirstName3", LastName = "LastName", 314 | DateOfBirth = DateTime.Parse("03/20/2012", UsCultureInfo.DateTimeFormat) 315 | }, 316 | new UserEntity 317 | { 318 | FirstName = "FirstName5", LastName = "LastName", 319 | DateOfBirth = DateTime.Parse("01/20/2018", UsCultureInfo.DateTimeFormat) 320 | }, 321 | }; 322 | 323 | 324 | } 325 | } 326 | -------------------------------------------------------------------------------- /src/MockQueryable/MockQueryable.Sample/MyServiceMoqTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Linq; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | using Microsoft.EntityFrameworkCore; 8 | using MockQueryable.Moq; 9 | using Moq; 10 | using NUnit.Framework; 11 | 12 | namespace MockQueryable.Sample 13 | { 14 | [TestFixture] 15 | public class MyServiceMoqTests 16 | { 17 | private static readonly CultureInfo UsCultureInfo = new CultureInfo("en-US"); 18 | 19 | [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] 20 | [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] 21 | [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] 22 | public void CreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) 23 | { 24 | //arrange 25 | var userRepository = new Mock(); 26 | var service = new MyService(userRepository.Object); 27 | var users = new List 28 | { 29 | new UserEntity {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, 30 | new UserEntity {FirstName = "ExistFirstName"}, 31 | new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, 32 | new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, 33 | new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)} 34 | }; 35 | //expect 36 | var mock = users.BuildMock(); 37 | userRepository.Setup(x => x.GetQueryable()).Returns(mock); 38 | //act 39 | var ex = Assert.ThrowsAsync(() => 40 | service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); 41 | //assert 42 | Assert.AreEqual(expectedError, ex.Message); 43 | } 44 | 45 | [TestCase("01/20/2012", "06/20/2018", 5)] 46 | [TestCase("01/20/2012", "06/20/2012", 4)] 47 | [TestCase("01/20/2012", "02/20/2012", 3)] 48 | [TestCase("01/20/2010", "02/20/2011", 0)] 49 | public async Task GetUserReports(DateTime from, DateTime to, int expectedCount) 50 | { 51 | //arrange 52 | var userRepository = new Mock(); 53 | var service = new MyService(userRepository.Object); 54 | var users = CreateUserList(); 55 | //expect 56 | var mock = users.BuildMock(); 57 | userRepository.Setup(x => x.GetQueryable()).Returns(mock); 58 | //act 59 | var result = await service.GetUserReports(from, to); 60 | //assert 61 | Assert.AreEqual(expectedCount, result.Count); 62 | } 63 | 64 | 65 | 66 | [TestCase("01/20/2012", "06/20/2018", 5)] 67 | [TestCase("01/20/2012", "06/20/2012", 4)] 68 | [TestCase("01/20/2012", "02/20/2012", 3)] 69 | [TestCase("01/20/2010", "02/20/2011", 0)] 70 | public async Task GetUserReports_AutoMap(DateTime from, DateTime to, int expectedCount) 71 | { 72 | //arrange 73 | var userRepository = new Mock(); 74 | var service = new MyService(userRepository.Object); 75 | var users = CreateUserList(); 76 | //expect 77 | var mock = users.BuildMock(); 78 | userRepository.Setup(x => x.GetQueryable()).Returns(mock); 79 | //act 80 | var result = await service.GetUserReportsAutoMap(from, to); 81 | //assert 82 | Assert.AreEqual(expectedCount, result.Count); 83 | } 84 | 85 | 86 | [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] 87 | [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] 88 | [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] 89 | public void DbSetCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) 90 | { 91 | //arrange 92 | var users = new List 93 | { 94 | new UserEntity {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, 95 | new UserEntity {FirstName = "ExistFirstName"}, 96 | new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, 97 | new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, 98 | new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)} 99 | }; 100 | var mock = users.AsQueryable().BuildMockDbSet(); 101 | var userRepository = new TestDbSetRepository(mock.Object); 102 | var service = new MyService(userRepository); 103 | //act 104 | var ex = Assert.ThrowsAsync(() => 105 | service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); 106 | //assert 107 | Assert.AreEqual(expectedError, ex.Message); 108 | } 109 | 110 | [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] 111 | [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] 112 | [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] 113 | public void DbSetCreatedFromCollectionCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) 114 | { 115 | //arrange 116 | var users = new List 117 | { 118 | new UserEntity {LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, 119 | new UserEntity {FirstName = "ExistFirstName"}, 120 | new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, 121 | new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)}, 122 | new UserEntity {DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat)} 123 | }; 124 | var mock = users.BuildMockDbSet(); 125 | var userRepository = new TestDbSetRepository(mock.Object); 126 | var service = new MyService(userRepository); 127 | //act 128 | var ex = Assert.ThrowsAsync(() => 129 | service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); 130 | //assert 131 | Assert.AreEqual(expectedError, ex.Message); 132 | } 133 | 134 | [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] 135 | public async Task DbSetCreateUser(string firstName, string lastName, DateTime dateOfBirth) 136 | { 137 | //arrange 138 | var userEntities = new List(); 139 | var mock = userEntities.AsQueryable().BuildMockDbSet(); 140 | 141 | mock.Setup(set => set.AddAsync(It.IsAny(), It.IsAny())) 142 | .Callback((UserEntity entity, CancellationToken _) => userEntities.Add(entity)); 143 | var userRepository = new TestDbSetRepository(mock.Object); 144 | var service = new MyService(userRepository); 145 | //act 146 | await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); 147 | // assert 148 | var entity = mock.Object.Single(); 149 | Assert.AreEqual(firstName, entity.FirstName); 150 | Assert.AreEqual(lastName, entity.LastName); 151 | Assert.AreEqual(dateOfBirth, entity.DateOfBirth); 152 | } 153 | 154 | [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] 155 | public async Task DbSetCreatedFromCollectionCreateUser(string firstName, string lastName, DateTime dateOfBirth) 156 | { 157 | //arrange 158 | var userEntities = new List(); 159 | var mock = userEntities.BuildMockDbSet(); 160 | 161 | mock.Setup(set => set.AddAsync(It.IsAny(), It.IsAny())) 162 | .Callback((UserEntity entity, CancellationToken _) => userEntities.Add(entity)); 163 | var userRepository = new TestDbSetRepository(mock.Object); 164 | var service = new MyService(userRepository); 165 | //act 166 | await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); 167 | // assert 168 | var entity = mock.Object.Single(); 169 | Assert.AreEqual(firstName, entity.FirstName); 170 | Assert.AreEqual(lastName, entity.LastName); 171 | Assert.AreEqual(dateOfBirth, entity.DateOfBirth); 172 | } 173 | 174 | [TestCase("01/20/2012", "06/20/2018", 5)] 175 | [TestCase("01/20/2012", "06/20/2012", 4)] 176 | [TestCase("01/20/2012", "02/20/2012", 3)] 177 | [TestCase("01/20/2010", "02/20/2011", 0)] 178 | public async Task DbSetGetUserReports(DateTime from, DateTime to, int expectedCount) 179 | { 180 | //arrange 181 | var users = CreateUserList(); 182 | var mock = users.AsQueryable().BuildMockDbSet(); 183 | var userRepository = new TestDbSetRepository(mock.Object); 184 | var service = new MyService(userRepository); 185 | //act 186 | var result = await service.GetUserReports(from, to); 187 | //assert 188 | Assert.AreEqual(expectedCount, result.Count); 189 | } 190 | 191 | [TestCase("01/20/2012", "06/20/2018", 5)] 192 | [TestCase("01/20/2012", "06/20/2012", 4)] 193 | [TestCase("01/20/2012", "02/20/2012", 3)] 194 | [TestCase("01/20/2010", "02/20/2011", 0)] 195 | public async Task DbSetCreatedFromCollectionGetUserReports(DateTime from, DateTime to, int expectedCount) 196 | { 197 | //arrange 198 | var users = CreateUserList(); 199 | var mock = users.BuildMockDbSet(); 200 | var userRepository = new TestDbSetRepository(mock.Object); 201 | var service = new MyService(userRepository); 202 | //act 203 | var result = await service.GetUserReports(from, to); 204 | //assert 205 | Assert.AreEqual(expectedCount, result.Count); 206 | } 207 | 208 | [TestCase] 209 | public async Task DbSetGetAllUserEntity() 210 | { 211 | //arrange 212 | var users = CreateUserList(); 213 | var mock = users.AsQueryable().BuildMockDbSet(); 214 | var userRepository = new TestDbSetRepository(mock.Object); 215 | //act 216 | var result = await userRepository.GetAll(); 217 | //assert 218 | Assert.AreEqual(users.Count, result.Count); 219 | } 220 | 221 | [TestCase] 222 | public async Task DbSetCreatedFromCollectionGetAllUserEntity() 223 | { 224 | //arrange 225 | var users = CreateUserList(); 226 | var mock = users.BuildMockDbSet(); 227 | var userRepository = new TestDbSetRepository(mock.Object); 228 | //act 229 | var result = await userRepository.GetAll(); 230 | //assert 231 | Assert.AreEqual(users.Count, result.Count); 232 | } 233 | 234 | [TestCase] 235 | public async Task DbSetFindAsyncUserEntity() 236 | { 237 | //arrange 238 | var userId = Guid.NewGuid(); 239 | var users = new List 240 | { 241 | new UserEntity 242 | { 243 | Id = Guid.NewGuid(), 244 | FirstName = "FirstName1", LastName = "LastName", 245 | DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) 246 | }, 247 | new UserEntity 248 | { 249 | Id = Guid.NewGuid(), 250 | FirstName = "FirstName2", LastName = "LastName", 251 | DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) 252 | }, 253 | new UserEntity 254 | { 255 | Id = userId, 256 | FirstName = "FirstName3", LastName = "LastName", 257 | DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) 258 | }, 259 | new UserEntity 260 | { 261 | Id = Guid.NewGuid(), 262 | FirstName = "FirstName3", LastName = "LastName", 263 | DateOfBirth = DateTime.Parse("03/20/2012", UsCultureInfo.DateTimeFormat) 264 | }, 265 | new UserEntity 266 | { 267 | Id = Guid.NewGuid(), 268 | FirstName = "FirstName5", LastName = "LastName", 269 | DateOfBirth = DateTime.Parse("01/20/2018", UsCultureInfo.DateTimeFormat) 270 | } 271 | }; 272 | 273 | var mock = users.AsQueryable().BuildMockDbSet(); 274 | mock.Setup(x => x.FindAsync(It.IsAny())).ReturnsAsync((object[] ids) => 275 | { 276 | var id = (Guid) ids.First(); 277 | return users.FirstOrDefault(x => x.Id == id); 278 | }); 279 | var userRepository = new TestDbSetRepository(mock.Object); 280 | 281 | //act 282 | var result = await ((DbSet)userRepository.GetQueryable()).FindAsync(userId); 283 | 284 | //assert 285 | Assert.IsNotNull(result); 286 | Assert.AreEqual("FirstName3", result.FirstName); 287 | } 288 | 289 | 290 | [TestCase] 291 | public async Task DbSetCreatedFromCollectionFindAsyncUserEntity() 292 | { 293 | //arrange 294 | var userId = Guid.NewGuid(); 295 | var users = new List 296 | { 297 | new UserEntity 298 | { 299 | Id = Guid.NewGuid(), 300 | FirstName = "FirstName1", LastName = "LastName", 301 | DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) 302 | }, 303 | new UserEntity 304 | { 305 | Id = Guid.NewGuid(), 306 | FirstName = "FirstName2", LastName = "LastName", 307 | DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) 308 | }, 309 | new UserEntity 310 | { 311 | Id = userId, 312 | FirstName = "FirstName3", LastName = "LastName", 313 | DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) 314 | }, 315 | new UserEntity 316 | { 317 | Id = Guid.NewGuid(), 318 | FirstName = "FirstName3", LastName = "LastName", 319 | DateOfBirth = DateTime.Parse("03/20/2012", UsCultureInfo.DateTimeFormat) 320 | }, 321 | new UserEntity 322 | { 323 | Id = Guid.NewGuid(), 324 | FirstName = "FirstName5", LastName = "LastName", 325 | DateOfBirth = DateTime.Parse("01/20/2018", UsCultureInfo.DateTimeFormat) 326 | } 327 | }; 328 | 329 | var mock = users.BuildMockDbSet(); 330 | mock.Setup(x => x.FindAsync(It.IsAny())).ReturnsAsync((object[] ids) => 331 | { 332 | var id = (Guid)ids.First(); 333 | return users.FirstOrDefault(x => x.Id == id); 334 | }); 335 | var userRepository = new TestDbSetRepository(mock.Object); 336 | 337 | //act 338 | var result = await ((DbSet)userRepository.GetQueryable()).FindAsync(userId); 339 | 340 | //assert 341 | Assert.IsNotNull(result); 342 | Assert.AreEqual("FirstName3", result.FirstName); 343 | } 344 | 345 | [TestCase] 346 | public async Task DbSetGetAllUserEntitiesAsync() 347 | { 348 | // arrange 349 | var users = CreateUserList(); 350 | 351 | var mockDbSet = users.AsQueryable().BuildMockDbSet(); 352 | var userRepository = new TestDbSetRepository(mockDbSet.Object); 353 | 354 | // act 355 | var result = await userRepository.GetAllAsync().ToListAsync(); 356 | 357 | // assert 358 | Assert.AreEqual(users.Count, result.Count); 359 | } 360 | 361 | 362 | [TestCase] 363 | public async Task DbSetToListAsyncAsync_ShouldReturnAllEntities_WhenSourceIsChanged() 364 | { 365 | // arrange 366 | var users = new List(); 367 | 368 | var mockDbSet = users.AsQueryable().BuildMockDbSet(); 369 | 370 | // act 371 | var result1 = await mockDbSet.Object.ToListAsync(); 372 | users.AddRange(CreateUserList()); 373 | var result2 = await mockDbSet.Object.ToListAsync(); 374 | 375 | // assert 376 | Assert.AreEqual(0, result1.Count); 377 | Assert.AreEqual(users.Count, result2.Count); 378 | } 379 | 380 | 381 | 382 | [TestCase] 383 | public async Task DbSetCreatedFromCollectionGetAllUserEntitiesAsync() 384 | { 385 | // arrange 386 | var users = CreateUserList(); 387 | 388 | var mockDbSet = users.BuildMockDbSet(); 389 | var userRepository = new TestDbSetRepository(mockDbSet.Object); 390 | 391 | // act 392 | var result = await userRepository.GetAllAsync().ToListAsync(); 393 | 394 | // assert 395 | Assert.AreEqual(users.Count, result.Count); 396 | } 397 | 398 | private static List CreateUserList() => new List 399 | { 400 | new UserEntity { FirstName = "FirstName1", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, 401 | new UserEntity { FirstName = "FirstName2", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, 402 | new UserEntity { FirstName = "FirstName3", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, 403 | new UserEntity { FirstName = "FirstName3", LastName = "LastName", DateOfBirth = DateTime.Parse("03/20/2012", UsCultureInfo.DateTimeFormat) }, 404 | new UserEntity { FirstName = "FirstName5", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2018", UsCultureInfo.DateTimeFormat) }, 405 | }; 406 | } 407 | } -------------------------------------------------------------------------------- /src/MockQueryable/MockQueryable.Sample/MyServiceNSubstituteTests.cs: -------------------------------------------------------------------------------- 1 | using MockQueryable.NSubstitute; 2 | using NSubstitute; 3 | using NUnit.Framework; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Globalization; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace MockQueryable.Sample 11 | { 12 | [TestFixture] 13 | public class MyServiceNSubstituteTests 14 | { 15 | private static readonly CultureInfo UsCultureInfo = new CultureInfo("en-US"); 16 | 17 | 18 | [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] 19 | [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] 20 | [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] 21 | public void CreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) 22 | { 23 | //arrange 24 | var userRepository = Substitute.For(); 25 | var service = new MyService(userRepository); 26 | var users = new List 27 | { 28 | new UserEntity{LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, 29 | new UserEntity{FirstName = "ExistFirstName"}, 30 | new UserEntity{DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, 31 | new UserEntity{DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, 32 | new UserEntity{DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, 33 | }; 34 | //expect 35 | var mock = users.BuildMock(); 36 | userRepository.GetQueryable().Returns(mock); 37 | //act 38 | var ex= Assert.ThrowsAsync(() => service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); 39 | //assert 40 | Assert.AreEqual(expectedError, ex.Message); 41 | 42 | } 43 | 44 | [TestCase("01/20/2012", "06/20/2018",5)] 45 | [TestCase("01/20/2012", "06/20/2012",4)] 46 | [TestCase("01/20/2012", "02/20/2012",3)] 47 | [TestCase("01/20/2010", "02/20/2011",0)] 48 | public async Task GetUserReports(DateTime from, DateTime to, int expectedCount) 49 | { 50 | //arrange 51 | var userRepository = Substitute.For(); 52 | var service = new MyService(userRepository); 53 | List users = CreateUserList(); 54 | 55 | //expect 56 | var mock = users.BuildMock(); 57 | userRepository.GetQueryable().Returns(mock); 58 | //act 59 | var result = await service.GetUserReports(from, to); 60 | //assert 61 | Assert.AreEqual(expectedCount, result.Count); 62 | } 63 | 64 | [TestCase("01/20/2012", "06/20/2018", 5)] 65 | [TestCase("01/20/2012", "06/20/2012", 4)] 66 | [TestCase("01/20/2012", "02/20/2012", 3)] 67 | [TestCase("01/20/2010", "02/20/2011", 0)] 68 | public async Task GetUserReports_AutoMap(DateTime from, DateTime to, int expectedCount) 69 | { 70 | //arrange 71 | List users = CreateUserList(); 72 | 73 | var mock = users.AsQueryable().BuildMockDbSet(); 74 | var userRepository = new TestDbSetRepository(mock); 75 | var service = new MyService(userRepository); 76 | //act 77 | var result = await service.GetUserReportsAutoMap(from, to); 78 | //assert 79 | Assert.AreEqual(expectedCount, result.Count); 80 | 81 | } 82 | 83 | [TestCase("01/20/2012", "06/20/2018", 5)] 84 | [TestCase("01/20/2012", "06/20/2012", 4)] 85 | [TestCase("01/20/2012", "02/20/2012", 3)] 86 | [TestCase("01/20/2010", "02/20/2011", 0)] 87 | public async Task GetUserReports_AutoMap_FromDbSetCreatedFromCollection(DateTime from, DateTime to, int expectedCount) 88 | { 89 | //arrange 90 | List users = CreateUserList(); 91 | 92 | var mock = users.BuildMockDbSet(); 93 | var userRepository = new TestDbSetRepository(mock); 94 | var service = new MyService(userRepository); 95 | //act 96 | var result = await service.GetUserReportsAutoMap(from, to); 97 | //assert 98 | Assert.AreEqual(expectedCount, result.Count); 99 | 100 | } 101 | 102 | [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] 103 | [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] 104 | [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] 105 | public void DbSetCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) 106 | { 107 | //arrange 108 | var users = new List 109 | { 110 | new UserEntity{LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, 111 | new UserEntity{FirstName = "ExistFirstName"}, 112 | new UserEntity{DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, 113 | new UserEntity{DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, 114 | new UserEntity{DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, 115 | }; 116 | var mock = users.AsQueryable().BuildMockDbSet(); 117 | var userRepository = new TestDbSetRepository(mock); 118 | var service = new MyService(userRepository); 119 | //act 120 | var ex = Assert.ThrowsAsync(() => service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); 121 | //assert 122 | Assert.AreEqual(expectedError, ex.Message); 123 | 124 | } 125 | 126 | 127 | [TestCase("AnyFirstName", "AnyExistLastName", "01/20/2012", "Users with DateOfBirth more than limit")] 128 | [TestCase("ExistFirstName", "AnyExistLastName", "02/20/2012", "User with FirstName already exist")] 129 | [TestCase("AnyFirstName", "ExistLastName", "01/20/2012", "User already exist")] 130 | public void DbSetCreatedFromCollectionCreateUserIfNotExist(string firstName, string lastName, DateTime dateOfBirth, string expectedError) 131 | { 132 | //arrange 133 | var users = new List 134 | { 135 | new UserEntity{LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, 136 | new UserEntity{FirstName = "ExistFirstName"}, 137 | new UserEntity{DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, 138 | new UserEntity{DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, 139 | new UserEntity{DateOfBirth = DateTime.Parse("01/20/2012",UsCultureInfo.DateTimeFormat)}, 140 | }; 141 | var mock = users.BuildMockDbSet(); 142 | var userRepository = new TestDbSetRepository(mock); 143 | var service = new MyService(userRepository); 144 | //act 145 | var ex = Assert.ThrowsAsync(() => service.CreateUserIfNotExist(firstName, lastName, dateOfBirth)); 146 | //assert 147 | Assert.AreEqual(expectedError, ex.Message); 148 | 149 | } 150 | 151 | [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] 152 | public async Task DbSetCreateUser(string firstName, string lastName, DateTime dateOfBirth) 153 | { 154 | //arrange 155 | var userEntities = new List(); 156 | var mock = userEntities.AsQueryable().BuildMockDbSet(); 157 | mock.AddAsync(Arg.Any()) 158 | .Returns(info => null) 159 | .AndDoes(info => userEntities.Add(info.Arg())); 160 | var userRepository = new TestDbSetRepository(mock); 161 | var service = new MyService(userRepository); 162 | //act 163 | await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); 164 | // assert 165 | var entity = mock.Single(); 166 | Assert.AreEqual(firstName, entity.FirstName); 167 | Assert.AreEqual(lastName, entity.LastName); 168 | Assert.AreEqual(dateOfBirth, entity.DateOfBirth); 169 | } 170 | 171 | [TestCase("AnyFirstName", "ExistLastName", "01/20/2012")] 172 | public async Task DbSetCreatedFromCollectionCreateUser(string firstName, string lastName, DateTime dateOfBirth) 173 | { 174 | //arrange 175 | var userEntities = new List(); 176 | var mock = userEntities.BuildMockDbSet(); 177 | mock.AddAsync(Arg.Any()) 178 | .Returns(info => null) 179 | .AndDoes(info => userEntities.Add(info.Arg())); 180 | var userRepository = new TestDbSetRepository(mock); 181 | var service = new MyService(userRepository); 182 | //act 183 | await service.CreateUserIfNotExist(firstName, lastName, dateOfBirth); 184 | // assert 185 | var entity = mock.Single(); 186 | Assert.AreEqual(firstName, entity.FirstName); 187 | Assert.AreEqual(lastName, entity.LastName); 188 | Assert.AreEqual(dateOfBirth, entity.DateOfBirth); 189 | } 190 | 191 | [TestCase("01/20/2012", "06/20/2018", 5)] 192 | [TestCase("01/20/2012", "06/20/2012", 4)] 193 | [TestCase("01/20/2012", "02/20/2012", 3)] 194 | [TestCase("01/20/2010", "02/20/2011", 0)] 195 | public async Task DbSetGetUserReports(DateTime from, DateTime to, int expectedCount) 196 | { 197 | //arrange 198 | var users = CreateUserList(); 199 | 200 | var mock = users.AsQueryable().BuildMockDbSet(); 201 | var userRepository = new TestDbSetRepository(mock); 202 | var service = new MyService(userRepository); 203 | //act 204 | var result = await service.GetUserReports(from, to); 205 | //assert 206 | Assert.AreEqual(expectedCount, result.Count); 207 | } 208 | 209 | [TestCase("01/20/2012", "06/20/2018", 5)] 210 | [TestCase("01/20/2012", "06/20/2012", 4)] 211 | [TestCase("01/20/2012", "02/20/2012", 3)] 212 | [TestCase("01/20/2010", "02/20/2011", 0)] 213 | public async Task DbSetCreatedFromCollectionGetUserReports(DateTime from, DateTime to, int expectedCount) 214 | { 215 | //arrange 216 | var users = CreateUserList(); 217 | 218 | var mock = users.BuildMockDbSet(); 219 | var userRepository = new TestDbSetRepository(mock); 220 | var service = new MyService(userRepository); 221 | //act 222 | var result = await service.GetUserReports(from, to); 223 | //assert 224 | Assert.AreEqual(expectedCount, result.Count); 225 | } 226 | 227 | [TestCase] 228 | public async Task DbSetGetAllUserEntity() 229 | { 230 | //arrange 231 | var users = CreateUserList(); 232 | var mock = users.AsQueryable().BuildMockDbSet(); 233 | var userRepository = new TestDbSetRepository(mock); 234 | //act 235 | var result = await userRepository.GetAll(); 236 | //assert 237 | Assert.AreEqual(users.Count, result.Count); 238 | } 239 | 240 | [TestCase] 241 | public async Task DbSetCreatedFromCollectionGetAllUserEntity() 242 | { 243 | //arrange 244 | var users = CreateUserList(); 245 | var mock = users.BuildMockDbSet(); 246 | var userRepository = new TestDbSetRepository(mock); 247 | //act 248 | var result = await userRepository.GetAll(); 249 | //assert 250 | Assert.AreEqual(users.Count, result.Count); 251 | } 252 | 253 | [TestCase] 254 | public async Task DbSetGetAllUserEntitiesAsync() 255 | { 256 | // arrange 257 | var users = CreateUserList(); 258 | 259 | var mockDbSet = users.AsQueryable().BuildMockDbSet(); 260 | var userRepository = new TestDbSetRepository(mockDbSet); 261 | 262 | // act 263 | var result = await userRepository.GetAllAsync().ToListAsync(); 264 | 265 | // assert 266 | Assert.AreEqual(users.Count, result.Count); 267 | } 268 | 269 | 270 | [TestCase] 271 | public async Task DbSetGetAllUserEntitiesAsync_ShouldReturnAllEntities_WhenSourceIsChanged() 272 | { 273 | // arrange 274 | var users = new List(); 275 | 276 | var mockDbSet = users.AsQueryable().BuildMockDbSet(); 277 | var userRepository = new TestDbSetRepository(mockDbSet); 278 | 279 | // act 280 | var result1 = await userRepository.GetAllAsync().ToListAsync(); 281 | users.AddRange(CreateUserList()); 282 | var result2 = await userRepository.GetAllAsync().ToListAsync(); 283 | 284 | // assert 285 | Assert.AreEqual(0, result1.Count); 286 | Assert.AreEqual(users.Count, result2.Count); 287 | } 288 | 289 | [TestCase] 290 | public async Task DbSetCreatedFromCollectionGetAllUserEntitiesAsync() 291 | { 292 | // arrange 293 | var users = CreateUserList(); 294 | 295 | var mockDbSet = users.BuildMockDbSet(); 296 | var userRepository = new TestDbSetRepository(mockDbSet); 297 | 298 | // act 299 | var result = await userRepository.GetAllAsync().ToListAsync(); 300 | 301 | // assert 302 | Assert.AreEqual(users.Count, result.Count); 303 | } 304 | 305 | [TestCase] 306 | public async Task DbSetGetOneUserTntityAsync() 307 | { 308 | // arrange 309 | var users = CreateUserList(); 310 | 311 | var mockDbSet = users.AsQueryable().BuildMockDbSet(); 312 | var userRepository = new TestDbSetRepository(mockDbSet); 313 | 314 | // act 315 | var result = await userRepository.GetAllAsync() 316 | .Where(user => user.FirstName == "FirstName1") 317 | .FirstOrDefaultAsync(); 318 | 319 | // assert 320 | Assert.AreEqual(users.First(), result); 321 | } 322 | 323 | [TestCase] 324 | public async Task DbSetCreatedFromCollectionGetOneUserTntityAsync() 325 | { 326 | // arrange 327 | var users = CreateUserList(); 328 | 329 | var mockDbSet = users.BuildMockDbSet(); 330 | var userRepository = new TestDbSetRepository(mockDbSet); 331 | 332 | // act 333 | var result = await userRepository.GetAllAsync() 334 | .Where(user => user.FirstName == "FirstName1") 335 | .FirstOrDefaultAsync(); 336 | 337 | // assert 338 | Assert.AreEqual(users.First(), result); 339 | } 340 | 341 | private static List CreateUserList() => new List 342 | { 343 | new UserEntity { FirstName = "FirstName1", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, 344 | new UserEntity { FirstName = "FirstName2", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, 345 | new UserEntity { FirstName = "FirstName3", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2012", UsCultureInfo.DateTimeFormat) }, 346 | new UserEntity { FirstName = "FirstName3", LastName = "LastName", DateOfBirth = DateTime.Parse("03/20/2012", UsCultureInfo.DateTimeFormat) }, 347 | new UserEntity { FirstName = "FirstName5", LastName = "LastName", DateOfBirth = DateTime.Parse("01/20/2018", UsCultureInfo.DateTimeFormat) }, 348 | }; 349 | 350 | } 351 | } 352 | -------------------------------------------------------------------------------- /src/MockQueryable/MockQueryable.Sample/TestDbSetRepository.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MockQueryable.Sample 7 | { 8 | public class TestDbSetRepository : IUserRepository 9 | { 10 | private readonly DbSet _dbSet; 11 | 12 | public TestDbSetRepository(DbSet dbSet) 13 | { 14 | _dbSet = dbSet; 15 | } 16 | public IQueryable GetQueryable() 17 | { 18 | return _dbSet; 19 | } 20 | 21 | public async Task CreateUser(UserEntity user) 22 | { 23 | await _dbSet.AddAsync(user); 24 | } 25 | 26 | public async Task> GetAll() { 27 | return await _dbSet.ToListAsync(); 28 | } 29 | 30 | public IAsyncEnumerable GetAllAsync() 31 | { 32 | return _dbSet.AsAsyncEnumerable(); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/MockQueryable/MockQueryable.Sample/TestsSetup.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | 3 | namespace MockQueryable.Sample 4 | { 5 | [SetUpFixture] 6 | public class TestsSetup 7 | { 8 | [OneTimeSetUp] 9 | public void SetUp() 10 | { 11 | MyService.Initialize(); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/MockQueryable/MockQueryable.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29102.190 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MockQueryable.Core", "MockQueryable.Core\MockQueryable.Core.csproj", "{7C85327C-5EE5-4C74-A1E5-9B7046CA6CFE}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MockQueryable.Moq", "MockQueryable.Moq\MockQueryable.Moq.csproj", "{8487D600-D0B2-42EB-80E3-2D1641847D46}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MockQueryable.Sample", "MockQueryable.Sample\MockQueryable.Sample.csproj", "{84563547-43DC-4A5D-AD8B-AC06166D05CF}" 11 | EndProject 12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MockQueryable.NSubstitute", "MockQueryable.NSubstitute\MockQueryable.NSubstitute.csproj", "{FAAD1998-2471-45B6-9458-807B314E050F}" 13 | EndProject 14 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MockQueryable.FakeItEasy", "MockQueryable.FakeItEasy\MockQueryable.FakeItEasy.csproj", "{744B09F5-6F09-4F02-A09C-BD55E619C4E8}" 15 | EndProject 16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MockQueryable.EntityFrameworkCore", "MockQueryable.EntityFrameworkCore\MockQueryable.EntityFrameworkCore.csproj", "{E3632875-02A1-4C4A-96AB-62089D9D3F4F}" 17 | EndProject 18 | Global 19 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 20 | Debug|Any CPU = Debug|Any CPU 21 | Release|Any CPU = Release|Any CPU 22 | EndGlobalSection 23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 24 | {7C85327C-5EE5-4C74-A1E5-9B7046CA6CFE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {7C85327C-5EE5-4C74-A1E5-9B7046CA6CFE}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {7C85327C-5EE5-4C74-A1E5-9B7046CA6CFE}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {7C85327C-5EE5-4C74-A1E5-9B7046CA6CFE}.Release|Any CPU.Build.0 = Release|Any CPU 28 | {8487D600-D0B2-42EB-80E3-2D1641847D46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {8487D600-D0B2-42EB-80E3-2D1641847D46}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {8487D600-D0B2-42EB-80E3-2D1641847D46}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {8487D600-D0B2-42EB-80E3-2D1641847D46}.Release|Any CPU.Build.0 = Release|Any CPU 32 | {84563547-43DC-4A5D-AD8B-AC06166D05CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {84563547-43DC-4A5D-AD8B-AC06166D05CF}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {84563547-43DC-4A5D-AD8B-AC06166D05CF}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {84563547-43DC-4A5D-AD8B-AC06166D05CF}.Release|Any CPU.Build.0 = Release|Any CPU 36 | {FAAD1998-2471-45B6-9458-807B314E050F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 37 | {FAAD1998-2471-45B6-9458-807B314E050F}.Debug|Any CPU.Build.0 = Debug|Any CPU 38 | {FAAD1998-2471-45B6-9458-807B314E050F}.Release|Any CPU.ActiveCfg = Release|Any CPU 39 | {FAAD1998-2471-45B6-9458-807B314E050F}.Release|Any CPU.Build.0 = Release|Any CPU 40 | {744B09F5-6F09-4F02-A09C-BD55E619C4E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 41 | {744B09F5-6F09-4F02-A09C-BD55E619C4E8}.Debug|Any CPU.Build.0 = Debug|Any CPU 42 | {744B09F5-6F09-4F02-A09C-BD55E619C4E8}.Release|Any CPU.ActiveCfg = Release|Any CPU 43 | {744B09F5-6F09-4F02-A09C-BD55E619C4E8}.Release|Any CPU.Build.0 = Release|Any CPU 44 | {E3632875-02A1-4C4A-96AB-62089D9D3F4F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 45 | {E3632875-02A1-4C4A-96AB-62089D9D3F4F}.Debug|Any CPU.Build.0 = Debug|Any CPU 46 | {E3632875-02A1-4C4A-96AB-62089D9D3F4F}.Release|Any CPU.ActiveCfg = Release|Any CPU 47 | {E3632875-02A1-4C4A-96AB-62089D9D3F4F}.Release|Any CPU.Build.0 = Release|Any CPU 48 | EndGlobalSection 49 | GlobalSection(SolutionProperties) = preSolution 50 | HideSolutionNode = FALSE 51 | EndGlobalSection 52 | GlobalSection(ExtensibilityGlobals) = postSolution 53 | SolutionGuid = {77E46EFE-EB0A-4D83-AA83-7F79C7FFB8CC} 54 | EndGlobalSection 55 | EndGlobal 56 | --------------------------------------------------------------------------------