title: Moqing Entity Framework 6 .Include() using DbSet<>
body: <p>I'd like to give the background to this question. Skip if you like. For quite a while I've paid close attention to the on going debates on stackoverflow and elsewhere regarding testing of code as it relates to EF.  One camp says, test directly against a database because of the differences between the Linq to Objects &amp; Sql and implementations.  Another says test by mocking.  </p>
  
  <p>Another split in opinion is the issue of using repositories, or accepting that DbContext and DbSet already provide a unit of work and repository pattern.  In the time that I've been using EF, I've tried about every combination of opinions provided by these camps.  Regardless of what I've done, EF proves to be hard to test.  </p>
  
  <p>I was excited to find the EF team made <a href="http://thedatafarm.com/blog/data-access/how-ef6-enables-mocking-dbsets-more-easily/" rel="noreferrer">DbSet more mockable</a> in EF 6.  They also provided <a href="http://msdn.microsoft.com/en-us/data/dn314429" rel="noreferrer">documentation</a> on how to mock DbSet, including async methods using Moq.  In working on my latest project involving Web Api I realized that if I could mock EF, I could skip writing repositories, as the normal reason for writing them is to make things testable.  Inspiration came after reading a few blog posts such as <a href="http://www.nogginbox.co.uk/blog/do-we-need-the-repository-pattern" rel="noreferrer">this...</a></p>
  
  <p>--End of background ---</p>
  
  <p>The actual problem is that following the example code given by the EF team on how to Moq DbSet, if .Include() is used in any code, an ArgumentNullException is thrown.</p>
  
  <p>Other <a href="https://stackoverflow.com/questions/20002873/entity-framework-6-mocking-include-method-on-dbset">related post on SO</a></p>
  
  <p>Here is my interface for DbContext:</p>
  
  <pre><code>public interface ITubingForcesDbContext
  {
      DbSet&lt;WellEntity&gt; Wells { get; set; }
  
      int SaveChanges();
  
      Task&lt;int&gt; SaveChangesAsync();
  
      Task&lt;int&gt; SaveChangesAsync(CancellationToken cancellationToken);
  }
  </code></pre>
  
  <p>This is the main entity that my controller deals with</p>
  
  <pre><code>public class WellEntity
  {
      public int Id { get; set; }
      public DateTime DateUpdated { get; set; }
      public String UpdatedBy { get; set; }
  
      [Required]
      public string Name { get; set; }
      public string Location { get; set; }
  
      public virtual Company Company { get; set; }
  
      public virtual ICollection&lt;GeometryItem&gt; GeometryItems
      {
          get { return _geometryItems ?? (_geometryItems = new Collection&lt;GeometryItem&gt;()); }
          protected set { _geometryItems = value; }
      }
      private ICollection&lt;GeometryItem&gt; _geometryItems;
  
      public virtual ICollection&lt;SurveyPoint&gt; SurveyPoints
      {
          get { return _surveyPoints ?? (_surveyPoints = new Collection&lt;SurveyPoint&gt;()); }
          protected set { _surveyPoints = value; }
      }
      private ICollection&lt;SurveyPoint&gt; _surveyPoints;
  
      public virtual ICollection&lt;TemperaturePoint&gt; TemperaturePoints
      {
          get { return _temperaturePoints ?? (_temperaturePoints = new Collection&lt;TemperaturePoint&gt;()); }
          protected set { _temperaturePoints = value; }
      }
      private ICollection&lt;TemperaturePoint&gt; _temperaturePoints;
  }
  </code></pre>
  
  <p>Here is the controller which directly uses an EF DbContext</p>
  
  <pre><code> [Route("{id}")]
   public async Task&lt;IHttpActionResult&gt; Get(int id)
   {
          var query = await TheContext.Wells.
                                     Include(x =&gt; x.GeometryItems).
                                     Include(x =&gt; x.SurveyPoints).
                                     Include(x =&gt; x.TemperaturePoints).
                                     SingleOrDefaultAsync(x =&gt; x.Id == id);
          if (query == null)
          {
              return NotFound();
          }
          var model = ModelFactory.Create(query);
          return Ok(model);
  }
  </code></pre>
  
  <p>Finally here is the failing test...</p>
  
  <p>Test Setup---</p>
  
  <pre><code>   [ClassInitialize]
     public static void ClassInitialize(TestContext testContest)
          {
  
              var well1 = new WellEntity { Name = "Well 1" };
              var well2 = new WellEntity { Name = "Well 2" };
              var well3 = new WellEntity { Name = "Well 3" };
              var well4 = new WellEntity { Name = "Well 4" };
  
              well1.GeometryItems.Add(new GeometryItem());
              well1.TemperaturePoints.Add(new TemperaturePoint());
              well1.SurveyPoints.Add(new SurveyPoint());
  
              well2.GeometryItems.Add(new GeometryItem());
              well2.TemperaturePoints.Add(new TemperaturePoint());
              well2.SurveyPoints.Add(new SurveyPoint());
  
              well3.GeometryItems.Add(new GeometryItem());
              well3.TemperaturePoints.Add(new TemperaturePoint());
              well3.SurveyPoints.Add(new SurveyPoint());
  
              well4.GeometryItems.Add(new GeometryItem());
              well4.TemperaturePoints.Add(new TemperaturePoint());
              well4.SurveyPoints.Add(new SurveyPoint());
  
              var wells = new List&lt;WellEntity&gt; { well1, well2, well3, well4 }.AsQueryable();
  
              var mockWells = CreateMockSet(wells);
  
              _mockContext = new Mock&lt;ITubingForcesDbContext&gt;();
              _mockContext.Setup(c =&gt; c.Wells).Returns(mockWells.Object);
     }
  
     private static Mock&lt;DbSet&lt;T&gt;&gt; CreateMockSet&lt;T&gt;(IQueryable&lt;T&gt; data) where T : class
      {
          var mockSet = new Mock&lt;DbSet&lt;T&gt;&gt;();
  
          mockSet.As&lt;IDbAsyncEnumerable&lt;T&gt;&gt;()
              .Setup(m =&gt; m.GetAsyncEnumerator())
              .Returns(new TestDbAsyncEnumerator&lt;T&gt;(data.GetEnumerator()));
  
          mockSet.As&lt;IQueryable&lt;T&gt;&gt;()
                 .Setup(m =&gt; m.Provider)
                 .Returns(new TestDbAsyncQueryProvider&lt;T&gt;(data.Provider));
  
          mockSet.As&lt;IQueryable&lt;T&gt;&gt;().Setup(m =&gt; m.Expression).Returns(data.Expression);
          mockSet.As&lt;IQueryable&lt;T&gt;&gt;().Setup(m =&gt;m.ElementType).Returns(data.ElementType);
          mockSet.As&lt;IQueryable&lt;T&gt;&gt;().Setup(m=&gt;m.GetEnumerator()).
          Returns(data.GetEnumerator());
  
          return mockSet;
     }
  
    [TestMethod]  
     public async Task Get_ById_ReturnsWellWithAllChildData()
      {
          // Arrange
          var controller = new WellsController(_mockContext.Object);
  
          // Act
          var actionResult = await controller.Get(1);
  
          // Assert
          var response = actionResult as OkNegotiatedContentResult&lt;WellModel&gt;;
          Assert.IsNotNull(response);
          Assert.IsNotNull(response.Content.GeometryItems);
          Assert.IsNotNull(response.Content.SurveyPoints);
          Assert.IsNotNull(response.Content.TemperaturePoints);
     }
  </code></pre>
  
  <p>TestDbAsyncQueryProvider &amp; TestDbAsyncEnumerator come directly from the referenced EF team documentation. I've tried several different variations for how I create the data for the mock, haven't had any luck with it.   </p>