-
-
Notifications
You must be signed in to change notification settings - Fork 821
Description
The problem is when I try to mock any method of the repository, for example GetFirstOne, it always return null during debugging.
C# mocking generic repository, unitOfWork and applying filter expression return exception that because repository always returns null
Method in service class that I wrote test for it:
public bool ResetPassword(ChangePasswordDto changePasswordDto)
{
var userQueryCriteria = UserOfMobileQueryCriteria(changePasswordDto.MobileNumber);
var user = _unitOfWork.UserRepository.GetFirstOne(userQueryCriteria);
if (user is null)
throw new RecordNotFoundException(_configReader.GetKey(ConfigKeys.ExceptionRecordNotFound.ToString()),
SharedErrorCode.RecordNotFound);
var verification = _verificationService.IsRecentlyVerified(user.Id, changePasswordDto.MobileNumber, changePasswordDto.NotificationChannelType);
if (verification is {IsVerified: false})
throw new UserNotVerifiedException(_configReader.GetKey(ConfigKeys.ExceptionUserIsNotVerified.ToString()),
SharedErrorCode.UserNotVerified);
var newPassword = _generalUtility.HashPassword(changePasswordDto.Password,
_configReader.GetKey(ConfigKeys.HashSalt.ToString()));
if (user.Password == newPassword)
throw new AuthenticationException(
_configReader.GetKey(ConfigKeys.ExceptionNewPasswordIsSimilarOldOne.ToString()),
SharedErrorCode.NewPasswordLikeOldOne);
user.Password = newPassword;
_unitOfWork.UserRepository.Update(user);
_unitOfWork.Save();
return true;
}
Implementation of UserOfMobileQueryCriteria method:
protected virtual BaseQueryCriteria<UserEntity> UserOfMobileQueryCriteria(string mobileNumber)
{
return new BaseQueryCriteria<UserEntity>(_ => _.MobileNumber == mobileNumber);
}
Implementation of GetFirstOne method:
public override T? GetFirstOne(IQuerySpecification<T> specification)
{
return ApplySpecification(specification).FirstOrDefault();
}
private IQueryable<T> ApplySpecification(IQuerySpecification<T> spec)
{
return GetQuery(_dbContext.Set<T>().AsQueryable(), spec);
}
private static IQueryable<T> GetQuery(IQueryable<T> queryable, IQuerySpecification<T> specification)
{
var query = queryable;
query = query.Where(specification.Filter);
return query;
}
Test:
[Fact]
public void ResetPasswordReturnTrue()
{
//Arrange
var changePasswordDto = new ChangePasswordDto()
{
Code = "1234",
Password = "stringst",
PasswordConfirmation = "stringst",
MobileNumber = "+111111111111",
NotificationChannelType = NotificationChannelType.SMS
};
var user = new UserEntity
{
Id = Guid.NewGuid().ToString(),
MobileNumber = changePasswordDto.MobileNumber,
Role = UserRoles.Parent,
FirstName = "Ahmad",
LastName = "Ke"
};
Expression<Func<UserEntity, bool>> e = x => x.MobileNumber == changePasswordDto.MobileNumber;
var userQueryBuilderMock = new Mock<BaseQueryCriteria<UserEntity>>(e);
_userServiceMock.Protected()
.Setup<BaseQueryCriteria<UserEntity>>("UserOfMobileQueryCriteria", changePasswordDto.MobileNumber)
.Returns( userQueryBuilderMock.Object );
_userUnitOfWorkMock.Setup(r =>
r.UserRepository.GetFirstOne(userQueryBuilderMock.Object))
.Returns(user);
var verification = new VerificationResponseDto
{
Code = changePasswordDto.Code,
Id = Guid.NewGuid().ToString(),
Recipient = user.MobileNumber,
IsVerified = true,
SendDate = DateTime.Today.AddMinutes(-10),
UserId = user.Id,
NotificationChannelType = changePasswordDto.NotificationChannelType
};
_verificationServiceMock.Setup(v => v.IsRecentlyVerified(user.Id, user.MobileNumber,NotificationChannelType.SMS)).Returns(verification);
//Act
var passwordChanged = _passwordService.ResetPassword(changePasswordDto);
//Assert
Assert.True(passwordChanged);
}
IUserUnitOfWork & UserUnitOfWork
public interface IUserUnitOfWork : IUnitOfWork
{
IRepository<UserEntity> UserRepository { get; }
}
public class UserUnitOfWork : IUserUnitOfWork
{
private readonly UserDbContext _userContext;
public IRepository<UserEntity> UserRepository { get; }
public UserUnitOfWork(UserDbContext userContext, IRepository<UserEntity> userRepository)
{
_userContext = userContext;
UserRepository = userRepository;
}
public void Save()
{
_userContext.SaveChanges();
}
public void Dispose()
{
_userContext.Dispose();
}
}
Result exception:
Exceptions.RecordNotFoundException
Exception of type 'Exceptions.RecordNotFoundException' was thrown.
at Application.UserService.ResetPassword(ChangePasswordDto changePasswordDto) in Application\UserPasswordService.cs:line 23
at UnitTests.User.Application.UserServiceTest.ResetPasswordReturnTrue() in User\Application\UserServiceTest.cs:line 91
