0

In my MVC controller ActionResult, I'm trying to do a merge type of query. This works when I run my code, but the Unit test for the ActionResult is failing.

First I get a revResources collection of specific resources, if any. There may be none.

Then I get a list of resources (projResources) joined to the revResources using DefaultIfEmpty.

During testing, I get an object in memory for projResources of type 'System.Linq.IQueryable', but when I try to get a List() I get:

NullReferenceException was unhandled by user code

I'm not sure what's null, or why this works at runtime but not during tests.

During the test, both db.RoleAssignment and db.ProfileSnapshot have valid records that relate correctly. I tested this by trying just select ra or select p.

Here's the code in question:

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

The StackTrace in the error detail looks like this:

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
M Kenyon II
  • 4,136
  • 4
  • 46
  • 94

1 Answers1

0

The problem is here :

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

You've tolerated the DefaultIfEmpty() value, this means that LINQ query may returns NULL for r entries .

Otherwise, you tried to access a property of r in the select clause

 // 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 

The exception is raised with ToList() because LINQ queries only run when readen.

There's a very clear topic about that here

Community
  • 1
  • 1
Perfect28
  • 11,089
  • 3
  • 25
  • 45
  • r.RoleAssignmentId may be null, and I'm okay with that. There will be cases where that is true. Is there a better way to allow that? Why does it work during RunTime, but during testing? (I'm guessing Linq to objects vs Linq to Entity?) Thank you for your help. – M Kenyon II Nov 25 '15 at 18:14
  • what should be OriginalSelected , Selected and RoleAssignmentId value when r is null ? – Perfect28 Nov 25 '15 at 18:16
  • false, false, and null – M Kenyon II Nov 25 '15 at 18:30
  • Do mind that depending on how the the `RoleAssignmentId` on `ProfileSnapshotViewModel` is defined `null` may not be a valid value. – Dbuggy Nov 26 '15 at 10:04