I'm struggling to get my head around unit testing. I've been following examples from both Nerd dinner and pro asp.net MVC framework, but as soon as I attempt my own quickly become stuck. As a test I have tried to build a validation class that simply using login information - usename and password to return a user from a repository. I've used this example as it's pretty simple to imagine what tests one might perform: Is_Password_Valid, Is_Username_Valid etc.
I've spent far too long trying to get my noggin around this. Could any one provide an example of how they might approach this as a unit test? I think once I've cracked this I'll be away.
//Arrange
string email = "[email protected]";
string password = "test";
//Arrange
List<Customer> customer = new List<Customer>();
customer.Add(new Customer { CustomerId = 1, Email = email, Password = "best", FirstName = "test", LastName = "wods", Sex = true });
mockRepos = new Moq.Mock<ICustomerRepository>();
mockRepos.Setup(x => x.GetCustomerByPasswordUsername(email, password)).Returns(customer.First());
Authenticate auth = new Authenticate(mockRepos.Object);
//Act
var result = auth.Login(email, password);
//Assert
//this is where I start to become unstuck??????
It definitely looks like you are on the right track, but let me try to explain how I would go about the test.
The actual system under test (SUT) here is the Authenticate
class. You have not told a lot about it, so I will assume the following:
It uses an instance of ICustomerRepository
to determine the existence of a user based on a combination of username (email) and password.
When the repostiory returns an instance of Customer
, given a username and password combination, the Login
method returns true. When the repository returns null
, the Login
method returns false.
I will use these assumptions in the following, but if they are not correct, I´m sure you will be able to change the tests so that they make sense for your scenario.
Test 1: When the username/password combination is correct, Login
will return true
public void LoginWillReturnTrueForAValidUsernamePasswordCombination()
{
string email = "[email protected]";
string password = "test";
//Dummy customer
var customer = new Customer();
//Create mock
var mockRepos = new Moq.Mock<ICustomerRepository>();
mockRepos.Setup(x => x.GetCustomerByPasswordUsername(
It.Is<string>(s => s == email),
It.Is<string>(s => s == password))
.Returns(customer);
var auth = new Authenticate(mockRepos.Object);
//Act
var result = auth.Login(email, password);
//Assert
Assert.IsTrue(result);
}
Note the use of It.Is
. Basically, the mock is set up in a way that it will only return the dummy customer object when the email and password defined in your test are passed to the GetCustomerByPasswordUsername
method.
Test 2: When the username/password combination is incorrect, Login
will return false
public void LoginWillReturnFalseForAnInvalidUsernamePasswordCombination()
{
string email = "[email protected]";
string password = "test";
//Create mock
var mockRepos = new Moq.Mock<ICustomerRepository>();
mockRepos.Setup(x => x.GetCustomerByPasswordUsername(
It.Is<string>(s => s == email),
It.Is<string>(s => s == password))
.Returns<Customer>(null);
var auth = new Authenticate(mockRepos.Object);
//Act
var result = auth.Login(email, password);
//Assert
Assert.IsFalse(result);
}
Although implicitly tested by the above tests, you may want to go a step further and write a test that ensures that the Login
method passes the right parameters to the repository. Such a test could look like the following:
Test 3: Login will invoke repository correctly
public void LoginWillInvokeGetCustomerByPasswordUsernameCorrectly()
{
string email = "[email protected]";
string password = "test";
//Create mock
var mockRepos = new Moq.Mock<ICustomerRepository>();
mockRepos.Setup(x => x.GetCustomerByPasswordUsername(
It.Is<string>(s => s == email),
It.Is<string>(s => s == password))
.Returns<Customer>(null)
.Verifiable();
var auth = new Authenticate(mockRepos.Object);
//Act (ignore result. We are only testing correct invocation)
auth.Login(email, password);
//Assert
mockRepos.Verify();
}
The Verify
method of a mock throws an exception if the methods that have been setup have not been called.
I hope this helps. Don't hesitate to ask if you have further questions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With