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

How do I perform a culture-insensitive sort using the DataGrid?
Call was rejected by callee. (Exception from HRESULT: 0x80010001 (RPC_E_CALL_REJECTED))
custom(HEX) formatter C# not working when editing cell of grid control
CancellationToken and CancellationTokenSource-How to use it?
Spooky scoping issues - C# - Switch - Case [duplicate]
Warning about non-existing existing resource, WPF
Serialize visual tree
What does <T?> mean in Class declaration? [duplicate]
Is it safe to make a List public for using it as a DataGridView's datasource?
Asp.net GridView OnRowUpdating
Masking a password argument in a console application
Difference between ternary (conditional) operator and if statement returning an Action
SingleOrNewIdentified(o => o.prop, value), setting o.prop when new
Error in removing a css class from code behind in asp.net
How to determine which trigger executed background task in Windows 8?
name dependent dependency injection

Categories

HOME
google-cloud-pubsub
kendo-ui-angular2
ide
packet
weblogic
ibm
c++builder
nagios
open-search-server
restheart
runtime
olap
jcodemodel
osclass
opengrok
css-float
ibatis
virtuemart
wallet
alert
typedef
rndis
pushbullet
procedural-generation
devexpress-mvc
oracle10g
knapsack-problem
boosting
setup-project
emr
overflow
unity3d-5
kofax
realloc
iterm2
fisheye
socketcluster
vertical-alignment
electron-packager
definition
cakephp-3.2
jenkins-2
lucee
px4
jcifs
fluent-nhibernate-mapping
sharpssh
critical-section
multi-select
chain
trusted-computing
breadcrumbs
copy-constructor
toggleclass
vga
jigsaw
key-value-store
syslog4j
vitamio
boost-bind
user-profile
boost-propertytree
videoview
serial-communication
avrcp
web-standards
android-networking
grails-3.0.9
data-representation
tidesdk
radgrid
veeam
launcher
register-allocation
sync
xmlserializer
triplestore
xps
facebook-java-api
mongoid4
grunt-wiredep
raddatepicker
caroufredsel
qgraphicsscene
usersettings
friendly-url
nx
phone-state-listener
django-tinymce
algol
idoc
openafs
expresso-store
dancer
joomla1.7
maven-eclipse-plugin
scriptmanager
pex-and-moles
backlight
norton
noise-reduction
cinder
table-valued-parameters
carbon-emacs
web-widget
pkcs#7
user-preferences

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