I have a completed application which I'm trying to write unit tests for (Yeah I know, talk about bad practices)
I have the following class here
public class UserManagementService : IUserManagementService
{
private static readonly IUserDao userDao = DataAccess.UserDao;
private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public LoginResponse Login(LoginRequest request)
{
var response = new LoginResponse(request.RequestId);
try
{
var user = userDao.GetByUserId(request.UserId);
if (user != null)
{
if (request.Password != "")
{
if (Authenticate(user, request.Password))
{
return response;
}
response.ErrorCode = "IncorrectPassword";
}
else
{
response.ErrorCode = "PasswordNotFound";
}
}
else
{
response.ErrorCode = "UserNotFound";
}
response.Acknowledge = AcknowledgeType.Failure;
return response;
}
catch (Exception ex)
{
Log.Error(ex);
response.Acknowledge = AcknowledgeType.Failure;
response.ErrorCode = "Exception";
return response;
}
}
public bool Authenticate(User user, string password)
{
if (user == null) return false;
using (var deriveBytes = new Rfc2898DeriveBytes(password, user.Salt))
{
var derivedPassword = deriveBytes.GetBytes(20);
if (!derivedPassword.SequenceEqual(user.Password)) return false;
}
return true;
}
}
userDao
follows the singleton pattern and this userDao.GetByUserId(request.UserId);
basically makes a call to my DB
I have written the following test, which will definitely give rise to some issues because I haven't figured how to Mock the userDao, and the Log
[Theory]
[InlineData("manager", "manager")]
public void LoginTest(string userId, string password)
{
// Arrange
// System under test
IUserManagementService userService = new UserManagementService();
var request = new LoginRequest().Prepare();
request.UserId = userId;
request.Password = password;
var expectedResponse = new LoginResponse(request.RequestId)
{
Acknowledge = AcknowledgeType.Success
};
//Act
var actualResponse = userService.Login(request);
//Assert
Assert.AreEqual(actualResponse.Acknowledge, expectedResponse.Acknowledge);
}
How can I refactor my Login
method, and UserManagementService
class without breaking too much of its structure to support unit testing so I can inject userDao
and Log
?
Any help would be great to help me kickstart what is going to be a long tedious process of refactoring the rest of my classes.
EDIT: This is a WCF service which follows the facade pattern. I have removed the 10 other static DAO similar to userDao to lessen the code clutter for this example.
userDao
follows the singleton pattern. \$\endgroup\$