title: Unit testing a controller with DI DbContext and Model that uses LINQ -- EF Core 2
body: <p><em>Before you start:</em></p>
  
  <ol>
  <li>We use PostgreSQL with Postgis extension (Can't use inMemoryDB option, because of Postgis' geometry that we are using)</li>
  <li>We do not use the repository pattern </li>
  <li>We use DbContext to access the DbModels and use Linq expressions on them</li>
  <li>We use Database First principle</li>
  </ol>
  
  <p>This sort of question has been asked before in varying degrees<a href="https://stackoverflow.com/questions/40476233/how-to-mock-an-async-repository-with-entity-framework-core">Like here, where they talk about it, however we do NOT implement the repository pattern </a> but I feel it has not been answered in a concise way and so I ask it again.
  References or general guide is welcomed, so thank you in advance.</p>
  
  <p>This is what I have so far.
  Controller:</p>
  
  <pre><code>public class StartTripController : Controller
  {
      private readonly DbContext _dbContext;
  
      public StartTripController(DbContext DbContext) =&gt; _DbContext = DbContext;
  
      [Route("connect")]
      [HttpGet]
      public async Task&lt;IActionResult&gt; StartTrip(MessageDto messageDto, StartTripDto startTripDto)
      {
  
          if (ModelState.ErrorCount &gt; 0)
              return StatusCode(400);
  
          var userToCheck = await _DbContext.User
                                              .Select(i =&gt; new UserDto { UserId = i.Id, PhoneId = i.PhoneId, AppInfoDto = new AppInfoDto { IsAppInDebug = false } })
                                              .SingleOrDefaultAsync(u =&gt; u.PhoneId == startTripDto.UserDto.PhoneId);   //checks if User is in DB, returns Null if not
  
          if (userToCheck == null) //user does not exist
          {
            //Make new User entity and save the changes to DB async
  
              UserDto newUserToReturn = new UserDto { UserId = user.Id, AppInfoDto = new AppInfoDto { IsAppInDebug = user.DebugMode } };
  
              return GenerateResponseWithStatus200(messageDto, newUserToReturn);
          }
  
          //user exists
          return GenerateResponseWithStatus200(messageDto, userToCheck);
      }
  </code></pre>
  
  <p>My Test looks like this:</p>
  
  <pre><code> public class StartTripControllerTest : ControllerTest&lt;StartTripController&gt;
  {
      private DbContext _mockDbContext;
  
      protected override StartTripController GetController()
      {
  
          var mockDbContext = new Mock&lt;DbContext&gt;();
  
          var userData = new List&lt;User&gt;
          {
              new User{PhoneId = "Phone1", Id = 1, ReportProviderId = 1, UserPhone = null, DebugMode = true, IpAddress = "empty", DeviceUser = null, Credential = null},
              new User{PhoneId = "Phone2", Id = 2, ReportProviderId = 2, UserPhone = null, DebugMode = true, IpAddress = "empty", DeviceUser = null, Credential = null}
          };
  
          var mockData = userData.AsQueryable().BuildMock(); //BuildMock is from https://github.com/romantitov/MockQueryable
          mockDbContext.Setup(x =&gt; ???what do I write here??).Returns(mockData.Object);
  
          return new StartTripController(mockDbContext.Object);
      }
  
  
  
      [Fact]
      public async System.Threading.Tasks.Task StartTrip_ReturnUser_JsonAsync()
      {
          // Arrange
          StartTripController startTripController = GetController();
  
          MessageDto messageDto = new MessageDto ();
          StartTripDto startTripDto = new StartTripDto();
           //code omitted for readiblity
          var result = await startTripController.StartTrip(messageDto, startTripDto);
      }
  }
  </code></pre>
  
  <p>Things I figured out:</p>
  
  <ol>
  <li>You have to Mock Interfaces in order for async methods to work <a href="https://msdn.microsoft.com/en-us/library/dn314429.aspx" rel="nofollow noreferrer">As per Microsoft's post</a></li>
  </ol>
  
  <p>Things I am stuck on:</p>
  
  <ol>
  <li>How do I mock the DbContext or I guess the Model in this case, so that I can use LINQ expressions, like I do I my regular code?</li>
  </ol>