Navigate / search

EntityFramework – asynchronous queries unit tests

Sometime ago I described how we can use Moq to unit tests elements of DbContext – please check post Mocking DbContext and DbSet with Moq. Unfortunate that post didn’t covered all issues related to that topic. I didn’t write about unit tests asynchronous queries. Today I want to come back to this issue.

We can treat a previous post as a starting point. We already have some code that help us to mock DbSet<T>. And right now we will extend that code to support asynchronous queries. It is very easy. We need only to implement IDbAsyncQueryProvider interface:

public class InMemoryAsyncQueryProvider<TEntity> : IDbAsyncQueryProvider
{
  private readonly IQueryProvider innerQueryProvider;
  
  internal InMemoryAsyncQueryProvider(IQueryProvider innerQueryProvider)
  {
    this.innerQueryProvider = innerQueryProvider;
  }

  public IQueryable CreateQuery(Expression expression)
  {
    return new InMemeoryAsyncEnumerable<TEntity>(expression);
  }

  public IQueryable<TElement> CreateQuery<TElement>(Expression expression)
  {
    return new InMemeoryAsyncEnumerable<TElement>(expression);
  }

  public object Execute(Expression expression)
  {
    return this.innerQueryProvider.Execute(expression);
  }
  
  public TResult Execute<TResult>(Expression expression)
  {
    return this.innerQueryProvider.Execute<TResult>(expression);
  }

  public Task<object> ExecuteAsync(Expression expression, CancellationToken cancellationToken)
  {
    return Task.FromResult(Execute(expression));
  }

  public Task<TResult> ExecuteAsync<TResult>(Expression expression, CancellationToken cancellationToken)
  {
    return Task.FromResult(Execute<TResult>(expression));
  }
}

Read more

Mocking DbContext and DbSet with Moq

I believe that during your work with unit tests with applications that are using database for data storage you will need to isolate layer that is responsible for providing data. In this example I will use Entity Framework as ORM.

Below you can find main elements of solution:

public class User
{
  public int Id { get; set; }
  public string Login { get; set; }
  public string Name { get; set; }
  public string Surname { get; set; }
  public bool AccountLocked { get; set; }
  public virtual List<Role> Roles { get; set; }
}

public class UsersContext : DbContext
{
  public virtual DbSet<User> Users { get; set; }
  public virtual DbSet<Role> Roles { get; set; }
}

public class UsersService
{
  private readonly UsersContext usersContext;
  
  public UsersService(UsersContext usersContext)
  {
    this.usersContext = usersContext;
  }
 
  public User AddUser(string login, string name, string surname)
  {
    var newUser = this.usersContext.Users.Add(
      new User
      {
        Login = login,
        Name = name,
        Surname = surname,
        AccountLocked = false
      });
  
    this.usersContext.SaveChanges();
    return newUser;
  }
 
  public IList<User> GetLockedUsers ()
  {
    return this.usersContext.Users.Where(x => x.AccountLocked).ToList();
  }
}

You have two possibilities to isolate UsersContext:

  • Add stub implementation for UsersContect class that will be used in unit test. It should be injected instead of UsersContext class in unit tests.
  • Mock UsersContext by using one of mocking frameworks – in this case Moq.

Read more

List of installed applications

Sometimes there is a need to find information about what software is installed on your computer. For example, we want to know, if anyone has already installed the program and where it is installed. This knowledge is needed, example, if you add a file to a directory with the program already installed. The simplest example is to write different kinds of plugins. The problem does not occur if the application has been installed in the default directory, we know, but this can no longer guarantee. Read more