Lyi*_*ise 27 c# unit-testing entity-framework moq
我目前正在尝试对通过实体框架运行的查询运行一些单元测试.查询本身在实时版本上运行没有任何问题,但单元测试总是失败.
我把它缩小到我对DbFunctions.TruncateTime的使用,但我不知道如何通过这种方式来获得单元测试以反映实时服务器上发生的情况.
这是我正在使用的方法:
public System.Data.DataTable GetLinkedUsers(int parentUserId)
{
var today = DateTime.Now.Date;
var query = from up in DB.par_UserPlacement
where up.MentorId == mentorUserId
&& DbFunctions.TruncateTime(today) >= DbFunctions.TruncateTime(up.StartDate)
&& DbFunctions.TruncateTime(today) <= DbFunctions.TruncateTime(up.EndDate)
select new
{
up.UserPlacementId,
up.Users.UserId,
up.Users.FirstName,
up.Users.LastName,
up.Placements.PlacementId,
up.Placements.PlacementName,
up.StartDate,
up.EndDate,
};
query = query.OrderBy(up => up.EndDate);
return this.RunQueryToDataTable(query);
}
Run Code Online (Sandbox Code Playgroud)
如果我注释掉带有DbFunctions的行,则测试全部通过(除了检查只运行给定日期的有效结果的那些).
有没有办法可以提供在这些测试中使用的DbFunctions.TruncateTime的模拟版本?本质上它应该只返回Datetime.Date,但在EF查询中不可用.
编辑:这是使用日期检查失败的测试:
[TestMethod]
public void CanOnlyGetCurrentLinkedUsers()
{
var up = new List<par_UserPlacement>
{
this.UserPlacementFactory(1, 2, 1), // Create a user placement that is current
this.UserPlacementFactory(1, 3, 2, false) // Create a user placement that is not current
}.AsQueryable();
var set = DLTestHelper.GetMockSet<par_UserPlacement>(up);
var context = DLTestHelper.Context;
context.Setup(c => c.par_UserPlacement).Returns(set.Object);
var getter = DLTestHelper.New<LinqUserGetLinkedUsersForParentUser>(context.Object);
var output = getter.GetLinkedUsers(1);
var users = new List<User>();
output.ProcessDataTable((DataRow row) => students.Add(new UserStudent(row)));
Assert.AreEqual(1, users.Count);
Assert.AreEqual(2, users[0].UserId);
}
Run Code Online (Sandbox Code Playgroud)
编辑2:这是来自相关测试的消息和调试跟踪:
Test Result: Failed
Message: Assert.AreEqual failed. Expected:<1>. Actual:<0>
Debug Trace: This function can only be invoked from LINQ to Entities
Run Code Online (Sandbox Code Playgroud)
从我读到的,这是因为没有这个方法的LINQ to Entities实现可以在这个地方用于单元测试,尽管有实时版本(因为它查询SQL服务器).
est*_*art 24
我知道我已经迟到了,但一个非常简单的解决方法就是编写自己的方法,该方法使用DbFunction属性.然后使用该函数而不是DbFunctions.TruncateTime.
[DbFunction("Edm", "TruncateTime")]
public static DateTime? TruncateTime(DateTime? dateValue)
{
return dateValue?.Date;
}
Run Code Online (Sandbox Code Playgroud)
使用此函数将在Linq to Entities使用时执行EDM TruncateTime方法,否则将运行提供的代码.
Lyi*_*ise 16
感谢所有人的帮助,我在阅读了qujck提到的垫片后,设法找到了一个对我有用的解决方案.添加一个假的EntityFramework程序集后,我可以通过将它们更改为以下来修复这些测试:
[TestMethod]
public void CanOnlyGetCurrentLinkedUsers()
{
using (ShimsContext.Create())
{
System.Data.Entity.Fakes.ShimDbFunctions.TruncateTimeNullableOfDateTime =
(DateTime? input) =>
{
return input.HasValue ? (DateTime?)input.Value.Date : null;
};
var up = new List<par_UserPlacement>
{
this.UserPlacementFactory(1, 2, 1), // Create a user placement that is current
this.UserPlacementFactory(1, 3, 2, false) // Create a user placement that is not current
}.AsQueryable();
var set = DLTestHelper.GetMockSet<par_UserPlacement>(up);
var context = DLTestHelper.Context;
context.Setup(c => c.par_UserPlacement).Returns(set.Object);
var getter = DLTestHelper.New<LinqUserGetLinkedUsersForParentUser>(context.Object);
var output = getter.GetLinkedUsers(1);
}
var users = new List<User>();
output.ProcessDataTable((DataRow row) => users.Add(new User(row)));
Assert.AreEqual(1, users.Count);
Assert.AreEqual(2, users[0].UserId);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8160 次 |
| 最近记录: |