2017-05-09 15 views
1

最近、私たちはMongoのリポジトリの汎用バージョンを実装しました。Moq C#MongoDB FindAsync戻り値

コードが呼び出され

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(); 
} 
リポジトリ

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; 
} 

も試したことがあり、次のシグネチャ

var matchingDealers = await _mongoRepository.FindAsync<Dealer>(x => x.Phones.Any(y => y.PhoneNumber == searchPhone)); 
var matchingDealers = await _mongoRepository.FindAsync(filter); 

FindAsync呼び出しを嘲笑するとき、私は返品に問題があります。この問題は、署名が一致しないか、非同期である可能性があります。

部品番号の設定 私は

_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()); 

戻りオブジェクトが

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 
     } 
    }); 
} 

例外

をしようとしました(電話番号の代わりにも It.IsAny<string>()と)両方のバージョンを試してみました
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() 

デバッグするとき、私は返すオブジェクトを取得していないため、ArgumentNullExceptionが発生しています。私は自分のセットアップで問題があることを知っていますが、私はどこにいるのか把握するのには苦労しています。私が想定し、テスト対象の方法を考える

+0

問題を再現するために使用できる[mcve]を提供してください。現在のところ、質問は特定の回答を得るための十分な文脈を提供していません。 – Nkosi

+0

@Nkosi - 申し訳ありません。私は情報過多の縄を学んでいるか、十分ではありません。何かが必要な場合は教えてください。それはasyncの問題でなければならない、私はちょうど正しい組み合わせを考え出すことができない。 –

答えて

0

_testFixture.MongoRepository 
    .Setup(_ => _.FindAsync(It.IsAny<FilterDefinition<Dealer>>())) 
    .ReturnsAsync(_testFixture.GetDealerWithZipCode()); 

これは

Task<IList<T>> FindAsync<T>(FilterDefinition<T> t) where T : IMongoModel 

属するを想定したテストの期待を簡素化すべきであるが、以下のようにリポジトリのモックをセットアップすることができるはずですDealerZipCodeAndLocationですリポジトリインタフェースは_testFixture.MongoRepositoryで提供されており、テスト対象のメソッドを行に安全に実行する必要があります

if (matchingDealer.Geocode == null) { 
    //... 

また、ロガーとジオロケーションキャッシュのような他の依存関係が、テストが期待どおりに実行されるように適切に偽装されていることを確認する必要があります。

+0

ありがとうございます。それは、Moqが署名を解決するために署名が一致しないという問題でした。 LinqまたはBuilders を使用する代わりに、Moqの設定でフィルタリングしました。結果のFilterDefinitionを渡す必要がありました。完全に私に起きたことはありません。 –

関連する問題