Unit testing with Mocks. Test behaviour not implementation
- by Kenny Eliasson
Hi..
I always had a problem when unit testing classes that calls other classes, for example I have a class that creates a new user from a phone-number then saves it to the database and sends a SMS to the number provided.
Like the code provided below.
public class UserRegistrationProcess : IUserRegistration
{
private readonly IRepository _repository;
private readonly ISmsService _smsService;
public UserRegistrationProcess(IRepository repository, ISmsService smsService)
{
_repository = repository;
_smsService = smsService;
}
public void Register(string phone)
{
var user = new User(phone);
_repository.Save(user);
_smsService.Send(phone, "Welcome", "Message!");
}
}
It is a really simple class but how would you go about and test it?
At the moment im using Mocks but I dont really like it
[Test]
public void WhenRegistreringANewUser_TheNewUserIsSavedToTheDatabase()
{
var repository = new Mock<IRepository>();
var smsService = new Mock<ISmsService>();
var userRegistration = new UserRegistrationProcess(repository.Object, smsService.Object);
var phone = "0768524440";
userRegistration.Register(phone);
repository.Verify(x => x.Save(It.Is<User>(user => user.Phone == phone)), Times.Once());
}
[Test]
public void WhenRegistreringANewUser_ItWillSendANewSms()
{
var repository = new Mock<IRepository>();
var smsService = new Mock<ISmsService>();
var userRegistration = new UserRegistrationProcess(repository.Object, smsService.Object);
var phone = "0768524440";
userRegistration.Register(phone);
smsService.Verify(x => x.Send(phone, It.IsAny<string>(), It.IsAny<string>()), Times.Once());
}
It feels like I am testing the wrong thing here?
Any thoughts on how to make this better?