Menu / szukaj

Pakiet Moq.EntityFramework.Helpers

Na blogu pojawiły się ostatnio dwa wpisy pokazujące w jaki sposób mnożna zamockować DbSet<TEntity> wykorzystując Moq:

Opisane rozwiązania połączyłem w jednej bibliotece i opublikowałem jako pakiet NuGet – Moq.EntityFramework.Helpers. Czytaj dalej

EntityFramework – testowanie zapytań asynchonicznych

Jakiś czas temu opisałem w jaki sposób można zamockować typy DbContext przy pomocy MoqMockowanie typów DbContext oraz DbSet z wykorzystaniem Moq. Temat ten nie został wtedy całkowicie wyczerpany. Pozostał jeden element do opisania – zapytania asynchoroniczne. Do tego elementu chciałbym dziś wrócić.

Punktem wyjście będzie poprzedni wpis – czyli mamy fragment kodu, który pozwala na zamockowanie DbSet<T>. Teraz tylko dodamy możliwość obsługi wywołań asynchronicznych. Aby to zrobić należy zaimplementować interfejs IDbAsyncQueryProvider:

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));
  }
}

Czytaj dalej

Mockowanie typów DbContext oraz DbSet z wykorzystaniem Moq

Pisząc testy jednostkowe w aplikacjach, które przechowują dane w bazie danych prędzej, czy później będziemy zmuszeni do odizolowania warstwy dostępu do bazy danych. W opisywanym przypadku jako ORM wykorzystywany jest Entity Framework.

Kod definiujący podstawowe elementy wygląda w następujący sposób:

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();
  }
}

Chcąc odizolować warstwę danych od aplikacji można wykorzystać jedną z dwóch opcji:

  • napisać dodatkową implementację klasy UsersContext, która na potrzeby testów jednostkowych będzie symulowała działanie bazy danych. Obiekt nowej klasy zostanie wstrzyknięty do obiektów, które do działania potrzebują klasę UsersContext.
  • wykorzystać jeden z dostępnych frameworków mockujących – w tym przypadku Moq.

Czytaj dalej

Lista zainstalowanych aplikacji

Czasami występuje potrzeba znalezienia informacji o tym jakie oprogramowanie jest zainstalowane na komputerze. Przykładowo chcemy się dowiedzieć, czy ktoś ma już zainstalowany dany program i gdzie jest zainstalowany. Wiedza ta jest potrzebna, gdy chcemy dodać przykładowo jakiś plik do katalogu z zainstalowanym już programem. Najprostszym przykładem jest pisanie różnego rodzaju pluginów. Problem nie występuje jeśli aplikacją została zainstalowana w katalogu domyślnym, który znamy, ale tego nie można już zagwarantować. Czytaj dalej