Mock Entity Framework long LINQ query

2019-05-29 14:27发布

Have a LINQ query expression (below) that want to test mocking the Entity Framework. To mock I am using the code: Entity Framework Testing with a Mocking Framework This works for other queries but doesn't work for this

var query = from vwPs in _reportingDbContext.VwAccountNumber
join ps in _reportingDbContext.PaymentSummary
  on new
  {
      Key1 = vwPs.Id,
      Key2 = vwPs.AccountNumber,
      Key3 = true,
      Key4 = true
  }
     equals
     new
     {
         Key1 = ps.Id,
         Key2 = ps.AccountNumber,
         Key3 = ps.PaymentDate >= fromDateTime,
         Key4 = ps.PaymentDate < toDateTime
     }
     into viewJoinPayment
from ps in viewJoinPayment.DefaultIfEmpty()
join prg in generatedReportIds
     on ps.PaymentRef equals prg
     into paymentJoinGenerated
from prgRow in paymentJoinGenerated.DefaultIfEmpty()
where vwPs.Id == Id
select new
{
    vwPs.AccountNumber,
    Payments = ps,
    ReportGenerated = prgRow
};

When execute the query the value in '_inner' at this point in the code

internal class TestDbAsyncEnumerator<T> : IDbAsyncEnumerator<T> {
    //...
    public Task<bool> MoveNextAsync(CancellationToken cancellationToken) 
    { 
        return Task.FromResult(_inner.MoveNext()); 
    }
    //...

}

? _inner {System.Linq.Enumerable.WhereSelectEnumerableIterator<<>f__AnonymousType11<<>f__AnonymousType10<<>f__AnonymousType9<<>f__AnonymousType7>, LL.Core.DataAccess.Models.PaymentSummaryEntity>, System.Collections.Generic.IEnumerable>, int>, <>f__AnonymousType12>} Current: null
Results View: Expanding the Results View will enumerate the IEnumerable

and when it executes the MoveNext() get exception

? _inner.MoveNext() '_inner.MoveNext()' threw an exception of type 'System.NullReferenceException' Data: {System.Collections.ListDictionaryInternal} HResult: -2147467261 HelpLink: null InnerException: null Message: "Object reference not set to an instance of an object." Source: "Anonymously Hosted DynamicMethods Assembly" StackTrace: " at lambda_method(Closure , <>f__AnonymousType92 )\r\n at System.Linq.Enumerable.<GroupJoinIterator>d__404.MoveNext()\r\n at System.Linq.Enumerable.d__223.MoveNext()\r\n at System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext()" TargetSite: {Int32 lambda_method(System.Runtime.CompilerServices.Closure, <>f__AnonymousType92[<>f__AnonymousType72[LL.Core.DataAccess.Models.VwAccountNumberEnt ity,System.Collections.Generic.IEnumerable`1[LL.Core.DataAccess.Models.PaymentSummaryEntity]],LL.Core.DataAccess.Models.PaymentSummaryEntity])}

Tried few changes including the one suggested in here DbSet mock, no results while calling ToList secondly

but still get the same problem. Please, can anybody give some light?

Verify query implementation with integration tests is not an option, as boss wants this to be tested at unit test level as all the other queries.

UPDATE: Thanks @Eduard Malakhov this is something tried. If remove the both 'DefaultIfEmpty' and run the query it doesn't throw the exception. But how can avoid the exception with the DefaultIfEmpty? How can I modify the mocking code to check this case, as the exception is not happening with a not mocked call?

var query = from vwPs in _charityReportingDbContext.VwCharityAccountNumber
join ps in _charityReportingDbContext.PaymentSummary
  on new
  {
      Key1 = vwPs.CharityId,
      Key2 = vwPs.AccountNumber,
      Key3 = true,
      Key4 = true
  }
     equals
     new
     {
         Key1 = ps.CharityId,
         Key2 = ps.AccountNumber,
         Key3 = ps.PaymentDate >= fromDateTime,
         Key4 = ps.PaymentDate < toDateTime
     }
     into viewJoinPayment
select new
{
    vwPs.AccountNumber,
};

1条回答
我欲成王,谁敢阻挡
2楼-- · 2019-05-29 15:21

My hacky 'solution' (is Friday and want to go home :). Removes the exception but unfortunately, doesn't give right results.

public Task<bool> MoveNextAsync(CancellationToken cancellationToken){ 
try
{
    return Task.FromResult(_inner.MoveNext());
}
catch (Exception ex)
{
    return Task.FromResult(false);
}}
查看更多
登录 后发表回答