Reputation: 2855
I'm testing an MVC controller and want to test that a Save method is called within one of my repositories. The controller is an AccountController which is attempting to Register a user. My AccountRepository has two methods, Save and Register. Register is calling Save after some checks. I'm not sure if I should just be testing whether Register gets called and running a seperate unit test on my Repository to verify if Save is called as part of calling Register or whether I've set up Moq incorrectly on my test.
Here's my test:
[TestMethod]
public void register_post_saves_valid_registration()
{
_mockMemberRepository.Setup(r => r.GetByEmail(It.IsAny<string>())).Returns(_testMember);
// Arrange
RegisterViewModel model = new RegisterViewModel()
{
Email = "[email protected]",
Password = "test123",
ConfirmPassword = "test123"
};
// Act
ActionResult result = _controller.Register(model);
// Assert
_mockMemberRepository.Verify(r => r.Register(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()), Times.Once());
_mockMemberRepository.Verify(r => r.Save(It.IsAny<Member>()), Times.Once());
}
This line:
_mockMemberRepository.Verify(r => r.Register(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()), Times.Once());
passes the test, but when I introduce the line below:
_mockMemberRepository.Verify(r => r.Save(It.IsAny<Member>()), Times.Once());
it fails.
Here is my Register method in my repository:
public MembershipCreateStatus Register(string email, string password, string confirm)
{
if (password.Equals(confirm))
{
try
{
Member m = GetByEmail(email);
if (m == null)
{
int format = (int)PasswordFormatEnum.Encrypted;
string salt = GenerateSalt();
string pass = EncodePassword(password, format, salt);
m = new Member()
{
Email = email,
Password = pass,
PasswordSalt = salt,
PasswordFormat = format
};
Save(m);
return MembershipCreateStatus.Success;
}
else
return MembershipCreateStatus.DuplicateEmail;
//"A user with that email address already exists. Please use the Forgotten Password link if you need to recover your password.";
}
catch (Exception ex)
{
_logger.LogError(ex);
return MembershipCreateStatus.ProviderError;
}
}
return MembershipCreateStatus.InvalidPassword;
}
My Save
method just takes a Member object and is a void method.
What am I doing wrong?
Upvotes: 0
Views: 802
Reputation: 3545
From the above code, it seems that the Save method is part of the Register method. If that is the case, then the Register method is part of the mockRepository, so it is mocked. Thus, the real implementation, which invokes Save will never be invoked.
Assuming the above is true (which I believe is, but can't really tell because I don't have the Controller code), you need to create separate tests:
Upvotes: 3