Unit testing with Mocks. Test behaviour not implementation

Posted by Kenny Eliasson on Stack Overflow See other posts from Stack Overflow or by Kenny Eliasson
Published on 2010-12-21T08:10:25Z Indexed on 2010/12/22 10:54 UTC
Read the original article Hit count: 267

Filed under:
|
|

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?

© Stack Overflow or respective owner

Related posts about c#

Related posts about unit-testing