简体   繁体   中英

Mock a call to IQueryable using moq

I'm trying to moq a repository I have which is defined as:

public IQueryable<TEntity> GetAll(Expression<Func<TEntity, bool>> predicate = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> include = null, bool disableTracking = true)

Is there a way to mock this? I want the query to execute, using the mock data i supply the repos. I'm not sure how to tell MOQ that when I call GetAll I want it to still run the query that is passed in, but do it aganist the dataset I supply. so it's not going to the db but against the mock set which I've configured. I'm able to create the data, it contain 12 records, but I want the getall moq call to execute it's query and filter it to just the 2 that should be returned.

The actual service where the call happens is:

var list = await _unitOfWork.GetRepository<CASE_ACTIVITY>().GetAll(predicate: x => x.SM_SITE_ID == siteId && x.CMS_USER_ID == userId
            && x.IS_DELETED == "N" && x.Appointment.IS_DELETED == "N" && x.Appointment.IS_ARCHIVED == "N" && x.IS_ARCHIVED == "N"
            && ((x.Appointment.APPOINTMENT_DATETIME.HasValue && x.Appointment.APPOINTMENT_DATETIME.Value.Date == DateTime.Today.Date)
                || (!x.Appointment.APPOINTMENT_DATETIME.HasValue && x.ACTIVITY_STATUS_ID == _appSettings.CASE_ACTIVITY_STATUS_ID_PENDING)))
            .Include(x => x.Activity_Lookup).Include(x => x.Appointment).ThenInclude(x => x.Cms_Client).Include(x => x.Cms_Case)
            .ToListAsync();

Assuming you have enough control over the GetRepository() method to make it return your mock repository, mocking the method itself is fairly straightforward (if a little verbose). I just dumped the GetAll method into an interface called IRepository , and this is what the mock looks like. Inside of the Returns method, you have access to each of the parameters to execute or ignore as you please.

  var mock = new Moq.Mock<IRepository>();
  mock.Setup(a => a.GetAll<int>(It.IsAny<Expression<Func<int, bool>>>(), It.IsAny<Func<IQueryable<int>, IOrderedQueryable<int>>>(), It.IsAny<Func<IQueryable<int>, IIncludableQueryable<int, object>>>(), It.IsAny<bool>()))
    .Returns<Expression<Func<int, bool>>, Func<IQueryable<int>, IOrderedQueryable<int>>, Func<IQueryable<int>, IIncludableQueryable<int, object>>, bool>((param1, param2, param3, param4) =>
    {
      return new[] { 1, 2, 3 }.AsQueryable();
    });

  var result = mock.Object.GetAll<int>();

From here, we can't help much without seeing more code. In abstract terms, though, you'll take your mock.Object (which is of type IRepository ) and feed it to whatever collection GetRepository() draws from. Also note, of course, that I used an int for the generic parameter -- you'll replace that with whatever type you're using. It may be possible to make a mock that accepts generic parameters, but that hopefully won't be necessary!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM