【发布时间】:2016-11-21 18:07:02
【问题描述】:
我想知道除了构建一个用于模拟FromSql 的包装器之外还有其他方法吗?我知道这种方法是静态的,但是由于他们将AddEntityFrameworkInMemoryDatabase 之类的东西添加到实体框架核心,我认为可能也有解决方案,我在我的项目中使用 EF Core 1.0.1。
我的最终目标是测试这个方法:
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 Core 中的 FromSql<T> 是静态扩展方法,我问这个问题是因为我认为我可能会从错误的角度解决这个问题,或者可能有比一个包装器,我会很感激对此的任何想法。
【问题讨论】:
-
在内部,EF 核心 FromSql extension method 在
IQueriable.Provider上调用CreateQuery,您可以查看模拟以实现您想要的。 -
你找到任何模拟FromSql的解决方案了吗?
-
@YawarMurtaza 不,有 Philippe 的答案,但我没有尝试过。
标签: c# unit-testing entity-framework-core moq