测试期间Linq出现错误,但运行时没有

本文关键字:运行时 错误 Linq 测试 | 更新日期: 2023-09-27 18:24:28

在我的MVC控制器ActionResult中,我正在尝试执行合并类型的查询。当我运行代码时,这是有效的,但ActionResult的单元测试失败了。

首先,我得到一个特定资源的revResources集合(如果有的话)。可能没有。

然后,我使用DefaultIfEmpty获得加入到revResources的资源(projResources)的列表。

在测试过程中,我在内存中为projResources获取了一个类型为"System.Linq.IQueryable"的对象,但当我尝试获取List()时,我得到了:

用户代码未处理NullReferenceException

我不确定什么是null,也不知道为什么这在运行时有效,但在测试期间无效。

在测试过程中,db.RoleAssignmentdb.ProfileSnapshot都有正确关联的有效记录。我只尝试了select raselect p来测试这一点。

这是有问题的代码:

var revResources = (from ra in db.RoleAssignment
                    where ra.RoleId == (int)SystemRoles.viewReview
                    select ra)
                .Distinct();
// At Runtime this may have zero (0) records and still functions.
var projResources = (from ra in db.RoleAssignment
                        join p in db.ProfileSnapshot on ra.AssigneeId equals p.ProfileSnapshotId
                        join r in revResources on ra.AssigneeId equals r.AssigneeId into rres
                        from r in rres.DefaultIfEmpty()
                        where ra.AssignedToId == review.RequestReview.ProjectSubmissionToReview.ProjectId
                        select new ProfileSnapshotViewModel
                        {
                            ProfileSnapshotId = p.ProfileSnapshotId,
                            Salutation = p.Salutation,
                            FirstName = p.FirstName,
                            MiddleName = p.MiddleName,
                            LastName = p.LastName,
                            Email = p.Email,
                            OriginalSelected = r.RoleAssignmentId != null,
                            Selected = r.RoleAssignmentId != null,
                            RoleAssignmentId = r.RoleAssignmentId
                        }).Distinct();
var assignedResList = projResources.ToList(); // This code fails

错误详细信息中的StackTrace如下所示:

at lambda_method(Closure , <>f__AnonymousType17`2 )
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Linq.Enumerable.<DistinctIterator>d__81`1.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at PublicationSystem.Controllers.ProjectController.ReviewResourceDetails(Guid id) in c:'Projects'BitLocker'publicationsystem'PublicationSystem'Controllers'ProjectController.cs:line 1200
at PublicationSystem_Test.Controllers.ProjectTests.Project_ReviewResourceDetails_Test() in c:'Projects'BitLocker'publicationsystem'PublicationSystem_Test'Controllers'ProjectTests.cs:line 74

测试期间Linq出现错误,但运行时没有

问题就在这里:

.....
from r in rres.DefaultIfEmpty()
..... 

您已经容忍了DefaultIfEmpty()值,这意味着LINQ查询可能会为r条目返回NULL。

否则,您试图访问select子句中r的属性

 // What should be the value of RoleAssignmentId  if r is null ? 
OriginalSelected = r != null && r.RoleAssignmentId != null,
Selected = r != null && r.RoleAssignmentId != null,
RoleAssignmentId = r == null ? null : r.RoleAssignmentId 

ToList()引发异常,因为LINQ查询仅在读取时运行。

这里有一个非常明确的主题