2016-11-21 12 views
0

私はFormSqlを嘲笑するためのラッパーを構築する以外の方法があるのだろうか?私はこのメソッドが静的であることを知っていますが、エンティティフレームワークのコアにAddEntityFrameworkInMemoryDatabaseのようなものを追加して以来、私はプロジェクトの中でEF Core 1.0.1を使用しています。エンティティフレームワークコアのFromSQLを嘲笑していますか?

私の最終目標は、このメソッドをテストすることです:

public List<Models.ClosestLocation> Handle(ClosestLocationsQuery message) 
    { 
     return _context.ClosestLocations.FromSql(
      "EXEC GetClosestLocations {0}, {1}, {2}, {3}", 
      message.LocationQuery.Latitude, 
      message.LocationQuery.Longitude, 
      message.LocationQuery.MaxRecordsToReturn ?? 10, 
      message.LocationQuery.Distance ?? 10 
     ).ToList(); 
    } 

私は私のクエリは、私が何かを行うことができ、エンティティフレームワーク6でthis answerに基づいて、私はそれに渡された同じオブジェクトで処理されていることを確認したいですこのように:私は私が間違って角度からこの問題にアプローチ可能性があるかがあるかもしれないと思うので

[Fact] 
    public void HandleInvokesGetClosestLocationsWithCorrectData() 
    { 
     var message = new ClosestLocationsQuery 
     { 
      LocationQuery = 
       new LocationQuery {Distance = 1, Latitude = 1.165, Longitude = 1.546, MaxRecordsToReturn = 1} 
     }; 

     var dbSetMock = new Mock<DbSet<Models.ClosestLocation>>(); 

     dbSetMock.Setup(m => m.FromSql(It.IsAny<string>(), message)) 
      .Returns(It.IsAny<IQueryable<Models.ClosestLocation>>()); 

     var contextMock = new Mock<AllReadyContext>(); 

     contextMock.Setup(c => c.Set<Models.ClosestLocation>()).Returns(dbSetMock.Object); 

     var sut = new ClosestLocationsQueryHandler(contextMock.Object); 
     var results = sut.Handle(message); 

     contextMock.Verify(x => x.ClosestLocations.FromSql(It.IsAny<string>(), It.Is<ClosestLocationsQuery>(y => 
      y.LocationQuery.Distance == message.LocationQuery.Distance && 
      y.LocationQuery.Latitude == message.LocationQuery.Latitude && 
      y.LocationQuery.Longitude == message.LocationQuery.Longitude && 
      y.LocationQuery.MaxRecordsToReturn == message.LocationQuery.MaxRecordsToReturn))); 
    } 

しかし、EF 6でSqlQuery<T>とは異なり、EFコアでFormSql<T>は、静的な拡張メソッドで、私はこの質問をしていますラッパーよりも優れた選択肢ですが、これについて何か考えていただければ幸いです。

+0

内部EFコア[FromSql拡張メソッド(https://github.com/aspnet/EntityFramework/blob/1fa247b038927a7d7438f666dc11253f64e0432d/src/Microsoft.EntityFrameworkCore.Relational/RelationalQueryableExtensions.cs)は、上の 'CreateQuery'への呼び出しを行っています'IQueriable.Provider'を見て、あなたが望むものを達成するためにそれを嘲笑することができます。 – Nkosi

答えて

1

FromSql<T>のコードを見ると、source.Provider.CreateQuery<TEntity>が呼び出されていることがわかります。これはあなたが嘲笑しなければならないものです。

はあなたのケースでは、私はあなたがそのようなもので、それをうまくできると思う:

var mockProvider = new Mock<IQueryProvider>(); 
mockProvider.Setup(s => s.CreateQuery(It.IsAny<MethodCallExpression>())) 
    .Returns(null as IQueryable); 
var mockDbSet = new Mock<DbSet<AllReady.Models.ClosestLocation>>(); 
mockDbSet.As<IQueryable<AllReady.Models.ClosestLocation>>() 
    .Setup(s => s.Provider) 
    .Returns(mockProvider.Object); 
var t = mockDbSet.Object; 
context.ClosestLocations = mockDbSet.Object; 

var sut = new ClosestLocationsQueryHandler(context); 
var results = sut.Handle(message); 

わからないどのようにすることができますその後MethodCallExpressionVerifyが、私はそれが可能だと思わ。あるいは、生成されたSQLをチェックする方法があるかもしれません。

関連する問題