'Mock repository that depends on DBContext using FakeItEasy
I'm developing an application with .NET Core and EF. I'm trying to implement some unit test using FakeItEasy and NUnit. Here's my problem. I've a DbContext as this one:
public class PostgresDbContext : IdentityDbContext<User, IdentityRole<int>, int> {
// Add DbSets
public virtual DbSet<Institution> Institutions { get; set; }
public virtual DbSet<Employee> Employees { get; set; }
...
Then I've a repository that uses PostgresDbContext:
public class UserRepository {
private readonly PostgresDbContext _dbContext;
public UserRepository(PostgresDbContext dbContext) {
_dbContext = dbContext;
}
...
And finally I've a service (the class that I'm trying to test) which uses UserRepository.
public class AuthService : BaseServiceAbstract {
private readonly SignInManager<User> _signInManager;
private readonly UserRepository _userRepository;
public AuthService(SignInManager<User> signInManager, UserRepository userRepository) {
_signInManager = signInManager;
_userRepository = userRepository;
}
The problem is when I try to Mock UserRepository in the following method:
[Test, Description("Should login when provided with right credentials")]
public void Login() {
var user = new Employee {Name = "user"};
var signInManger = A.Fake<SignInManager<User>>();
var userRepository = A.Fake<UserRepository>();
_authService = new AuthService(signInManger, userRepository);
A.CallTo(() => userRepository.FindUserByUsername("user"))
.Returns(user);
_authService.Login("user", "password");
}
I throws me the error:
FakeItEasy.Core.FakeCreationException :
Failed to create fake of type DAL.Repositories.UserRepository:
The constructors with the following signatures were not tried:
(*DAL.PostgresDbContext)
Types marked with * could not be resolved. Please provide a Dummy Factory to enable these constructors.
Any idea?
Solution 1:[1]
To create a fake UserRepository, FakeItEasy needs an instance of PostgresDbContext. So it tries to create a fake one, but doesn't succeed (I don't have enough details to determine why exactly). Anyway, mocking a DbContext is always difficult.
Instead of mocking UserRepository directly, consider introducing a IUserRepository interface, implemented by UserRepository, and inject that in your AuthService. Mocking interfaces is generally much easier than mocking classes.
In general, you should avoid making your classes depend on other concrete classes. They should depend on abstractions instead. This will make your life much easier when writing unit tests.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Thomas Levesque |
