c#


Moq C# MongoDB FindAsync return value


Recently we implemented a generic version of a repository for Mongo.
Repository
public async Task<IList<T>> FindAsync<T>(FilterDefinition<T> t) where T : IMongoModel
{
var collection = _connection.GetCollection<T>();
var result = await collection.FindAsync<T>(t);
return await result.ToListAsync();
}
public async Task<IList<T>> FindAsync<T>(Expression<Func<T, bool>> filter) where T : IMongoModel
{
var collection = _connection.GetCollection<T>();
var result = await collection.FindAsync(filter);
return await result.ToListAsync();
}
Code Being Called
private async Task<MongoDb.Advertisement.Service.Models.AdvertisementFiles.Advertisement> DealerZipCodeAndLocation(MongoDb.Advertisement.Service.Models.AdvertisementFiles.Advertisement advertisement, string searchPhone)
{
var matchingDealers = await _mongoRepository.FindAsync(Builders<Dealer>.Filter.ElemMatch(y => y.Phones, z => z.PhoneNumber == searchPhone));
if (!matchingDealers.Any())
{
return advertisement;
}
if (matchingDealers.Count > 1)
{
_logger.Warning("More than one dealer found with {PhoneNumber}", searchPhone);
}
var matchingDealer = matchingDealers.FirstOrDefault();
if (matchingDealer.Geocode == null)
{
var geoCode = await _geoLocationCache.GetGeocodByZipCode(matchingDealer.Address.ZipCode);
if (geoCode.status != "OK")
{
return advertisement;
}
advertisement.Geocode = geoCode;
advertisement.ZipCode = matchingDealer.Address.ZipCode;
await UpdateGeocode<Dealer>(matchingDealer.Id, geoCode);
}
return advertisement;
}
Have also tried following signatures
var matchingDealers = await _mongoRepository.FindAsync<Dealer>(x => x.Phones.Any(y => y.PhoneNumber == searchPhone));
var matchingDealers = await _mongoRepository.FindAsync(filter);
When mocking out the FindAsync call, I am having difficulty with the return. The issue is either with the signature not matching, or more likely with async.
Moq Setup
I have tried both versions (also with It.IsAny<string>() in place of the phone number)
_testFixture.MongoRepository.Setup(x => x.FindAsync(Builders<Dealer>.Filter.ElemMatch(y => y.Phones, z => z.PhoneNumber == _testFixture.GetAdvertisementWithNoZipCode().OriginalPhoneNumber))).Returns(Task.FromResult(_testFixture.GetDealerWithZipCode()));
_testFixture.MongoRepository.Setup(x => x.FindAsync(Builders<Dealer>.Filter.ElemMatch(y => y.Phones, z => z.PhoneNumber == _testFixture.GetAdvertisementWithNoZipCode().OriginalPhoneNumber))).ReturnsAsync(_testFixture.GetDealerWithZipCode());
Return Objects Tried
public IList<Dealer> GetDealerWithZipCode()
{
return new List<Dealer>
{
new Dealer
{
Active = true,
DealerName = "City Chevrolet",
Phones = new List<Phone>
{
new Phone
{
PhoneNumber = "4033809999"
}
},
MasterCode = "CHEV01",
RevisionDate = DateTime.UtcNow
}
};
}
public async Task<IList<Dealer>> GetDealerWithZipCode()
{
return await Task.Run(() => new List<Dealer>
{
new Dealer
{
Active = true,
DealerName = "City Chevrolet",
Phones = new List<Phone>
{
new Phone
{
PhoneNumber = "4033809999"
}
},
MasterCode = "CHEV01",
RevisionDate = DateTime.UtcNow
}
});
}
Exception
System.ArgumentNullException: Value cannot be null.
Parameter name: source
at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source)
at Domain.Advertisement.Service.BackgroundProcessors.ZipCodeAndLocationProcessor.<DealerZipCodeAndLocation>d__5.MoveNext() in C:\Repos\Vader\AdSvc\domain\domain.advertisement.service\BackgroundProcessors\ZipCodeAndLocationProcessor.cs:line 60
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Domain.Advertisement.Service.BackgroundProcessors.ZipCodeAndLocationProcessor.<ProcessVehicleAdvertisementLocation>d__4.MoveNext() in C:\Repos\Vader\AdSvc\domain\domain.advertisement.service\BackgroundProcessors\ZipCodeAndLocationProcessor.cs:line 42
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Domain.Advertisement.Service.Tests.Processors.ZipCodeAndLocation.ZipCodeAndLocationProcessorFacts.<ProcessVehicleAdvertisementLocation_AdLineHasEmptyZipCodePhoneMatchesDealer_GeocodeIsAddedToAdvertisement>d__3.MoveNext() in C:\Repos\Vader\AdSvc\tests\domain.advertisement.service.tests\Processors\ZipCodeAndLocation\ZipCodeAndLocationProcessorFacts.cs:line 47
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Xunit.Sdk.TestInvoker`1.<>c__DisplayClass48_1.<<InvokeTestMethodAsync>b__1>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Xunit.Sdk.ExecutionTimer.<AggregateAsync>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Xunit.Sdk.ExceptionAggregator.<RunAsync>d__9.MoveNext()
When I debug I am getting an ArgumentNullException because I am not getting my return object. I know I have an issue in my setup, but I am struggling to figure out where.
Given the method under test which I assume is DealerZipCodeAndLocation you should be able to setup the repository mock as follows
_testFixture.MongoRepository
.Setup(_ => _.FindAsync(It.IsAny<FilterDefinition<Dealer>>()))
.ReturnsAsync(_testFixture.GetDealerWithZipCode());
this should simplify the expectations for the test assuming
Task<IList<T>> FindAsync<T>(FilterDefinition<T> t) where T : IMongoModel
belongs to the repository interface provided by _testFixture.MongoRepository, and should safely exercise the method under test to the line
if (matchingDealer.Geocode == null) {
//...
Where you would also need to make sure that the other dependencies like the logger and geo location cache are properly mocked for the test to be exercised as expected.

Related Links

siganlr in IIS site with multiple applications
Windows Form Application using HTML
Improve performence of querys working with c#, Entity Framework
Asp.net web page continous spinnig on live after completion of tasks and giving XML parser error, while works fine on local
WPF - How to draw lines between custom controls programmatically
Added text value disappears when clicking a button in view model
You can use the navigation bar to switch contex
Unable to resolve service for type 'ClassLibrary.ApplicationDbContext' - an unhandled exception occurred
Binding Data to Blend visual studio 2015
Extract an archive with progress bar?
Xamarin forms VS 2017 - exception rendering the control
Use SelectMany and GroupBy
How to display certain panels in an order that is dependent on a property in the panel?
“The given ColumnMapping does not match up with any column in the source or destination” while importing Excel into SQL Server using C#
C# How to convert specific lower-case letters to uppercase and uppercase letters to lowercase at the same time
how update more than one records on datagridview

Categories

HOME
actionscript-3
autohotkey
internet-explorer
indexing
twitter-bootstrap
grizzly
liquibase
postsharp
ebay-api
mifare
singleton
opc-ua
ms-application-insights
opengl-es
grid
pip
ionic-native
soap-client
angularjs-ng-repeat
angular-universal
oxid
console-application
openstack-horizon
bookmarklet
game-engine
facebook-marketing-api
smooth-scrolling
vivado-hls
civicrm
django-rest-auth
ampscript
webgl-earth
descriptor
include-path
grunt-contrib-uglify
continuous-fourier
dynamic-memory-allocation
checkmarx
spring-data-gemfire
keil
ragel
gstreamer-1.0
iterm2
idea-plugin
azure-web-roles
glide-image-library
google-cloud-powershell
directadmin
grails-2.0
jenkins-2
activeandroid
geminabox
django-tables2
lucee
audio-fingerprinting
wink
seyren
critical-section
reloaddata
overhead
ios-keyboard-extension
group
disconnect
normalisation
git-cherry-pick
php-java-bridge
phpdesigner
mod
trendline
fadein
web-performance
matlab-engine
random-sample
notice
lytro
hexagonal-tiles
android-filterable
avd
accpac
google-experiments
nsq
dojox.grid
diffmerge
disparity-mapping
xts
banana-pi
rda
traceur
pthreads-win32
facebook-likebox
dylan
sygic
ojb
mandelbrot
azure-scheduler
removeall
coinbase-php
biztalk-deployment
phone-state-listener
yii-components
orchestration
wpml
netzke
custom-cursor
optimistic-concurrency
umfpack
zend-validate
overlays
javah
subdirectories
nyromodal
silverlight-2.0
pkcs#7
data-formats
scala-designer
office-2003
hotfix

Resources

Mobile Apps Dev
Database Users
javascript
java
csharp
php
android
MS Developer
developer works
python
ios
c
html
jquery
RDBMS discuss
Cloud Virtualization
Database Dev&Adm
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App