mardi 13 septembre 2016

Getting null return values from methods when using Moq

I have never used Moq for mocking context before and I was pretty sure it is a easy job to do since I have some experience with RhinoMock. But when I am trying to do simply thing, to use UnitTest to check if object is created correctly I do not get expected results.

Lets say I have User entity that has some data inside of it. This is User class:

public string UserName { get; set; }
public string Password { get; set; }
public Person Person { get; set; }
public List<Role> Roles { get; set; }
public ISecurityService SecurityService { get; set; }
public byte[] Salt { get; set; }

public User(string userName, string password, Person person, ISecurityService securityService)
{
    UserName = userName;
    Person = person;
    Roles = new List<Role>();
    SecurityService = new SecurityService();
    Salt = securityService.GenerateSalt(4);
    Password = securityService.GenerateHashedAndSaltedPassword(password, Salt);
}

I am using salting and hashing for my password on user creation. Methods GenerateSalt(int salt) and GeneraHasedAndSaltedPassword(stiring password, byte[] salt) are part of SecurityService class. This is how I have implemented class:

I have ISecurityService interface:

public interface ISecurityService
{
    byte[] GenerateSalt(int saltSize);
    string GenerateHashedAndSaltedPassword(string password, byte[] salt);
}

And SecurityService class is implementing that interface:

public class SecurityService : ISecurityService
{
    string ISecurityService.GenerateHashedAndSaltedPassword(string password, byte[] salt)
    {
        HashAlgorithm algorithm = new SHA1Managed();
        var plainTextBytes = Encoding.ASCII.GetBytes(password);

        var plainTextWithSaltBytes = AppendByteArray(plainTextBytes, salt);
        var saltedSHA1Bytes = algorithm.ComputeHash(plainTextWithSaltBytes);
        var saltedSHA1WithAppendedSaltBytes = AppendByteArray(saltedSHA1Bytes, salt);

        return "{SSHA}" + Convert.ToBase64String(saltedSHA1WithAppendedSaltBytes);
    }

    byte[] ISecurityService.GenerateSalt(int saltSize)
    {
        var rng = new RNGCryptoServiceProvider();
        var buff = new byte[saltSize];
        rng.GetBytes(buff);
        return buff;
    }

    private byte[] AppendByteArray(byte[] byteArray1, byte[] byteArray2)
    {
        var byteArrayResult =
                new byte[byteArray1.Length + byteArray2.Length];

        for (var i = 0; i < byteArray1.Length; i++)
            byteArrayResult[i] = byteArray1[i];
        for (var i = 0; i < byteArray2.Length; i++)
            byteArrayResult[byteArray1.Length + i] = byteArray2[i];

        return byteArrayResult;
    }
}

In my Unit tests I have Init() method:

[SetUp]
public void Init()
{
    var securityServiceMock = new Mock<ISecurityService>();
    userName = "testUser";
    password = "123";
    userBuilder = new UserBuilder(userName, password, person, securityServiceMock.Object);
    user = new User(userName, password, person, securityServiceMock.Object);
}

This is where I want to create mock for ISecurityService. I am passing password that is not hashed to a constructor of User class. My expectation is that when new user is created I have hashed password that belongs to him.

But when I use debugger to see what is happening on creation for:

Salt = securityService.GenerateSalt(4);

I get:

{byte[0]}

And for password:

Password = securityService.GenerateHashedAndSaltedPassword(password, Salt);

I get null value. Debugger never hits this methods.

Anybody has any idea what I am doing wrongly here. Do I pass wrong value when creating a mock or I am expecting to get something I cannot get on new object initialization?

Aucun commentaire:

Enregistrer un commentaire