I am embarking upon my first journey of test driven development in C#. To get started I’m using MSTest and Rhino.Mocks. I am attempting to write my first unit tests against my ICustomerRepository. It seems tedious to new up a Customer for each test method. In ruby-on-rails I’d create a seed file and load the customer for each test. It seems logical that I could put this boiler plate Customer into a property of the test class but then I would run the risk of it being modified. What are my options for simplifying this code?
[TestMethod]
public class CustomerTests : TestClassBase
{
[TestMethod]
public void CanGetCustomerById()
{
// arrange
var customer = new Customer()
{
CustId = 5,
DifId = "55",
CustLookupName = "The Dude",
LoginList = new[] {
new Login { LoginCustId = 5, LoginName = "tdude" } }
};
var repository = Stub<ICustomerRepository>();
// act
repository.Stub(rep => rep.GetById(5)).Return(customer);
// assert
Assert.AreEqual(customer, repository.GetById(5));
}
[TestMethod]
public void CanGetCustomerByDifId()
{
// arrange
var customer = new Customer()
{
CustId = 5,
DifId = "55",
CustLookupName = "The Dude",
LoginList = new[] {
new Login { LoginCustId = 5, LoginName = "tdude" } }
};
var repository = Stub<ICustomerRepository>();
// act
repository.Stub(rep => rep.GetCustomerByDifID("55")).Return(customer);
// assert
Assert.AreEqual(customer, repository.GetCustomerByDifID("55"));
}
[TestMethod]
public void CanGetCustomerByLogin()
{
// arrange
var customer = new Customer()
{
CustId = 5,
DifId = "55",
CustLookupName = "The Dude",
LoginList = new[] {
new Login { LoginCustId = 5, LoginName = "tdude" } }
};
var repository = Stub<ICustomerRepository>();
// act
repository.Stub(rep =>
rep.GetCustomerByLogin("tdude")).Return(customer);
// assert
Assert.AreEqual(customer, repository.GetCustomerByLogin("tdude"));
}
}
Test Base Class
public class TestClassBase
{
protected T Stub<T>() where T : class
{
return MockRepository.GenerateStub<T>();
}
}
ICustomerRepository and IRepository
public interface ICustomerRepository : IRepository<Customer>
{
IList<Customer> FindCustomers(string q);
Customer GetCustomerByDifID(string difId);
Customer GetCustomerByLogin(string loginName);
}
public interface IRepository<T>
{
void Save(T entity);
void Save(List<T> entity);
bool Save(T entity, out string message);
void Delete(T entity);
T GetById(int id);
ICollection<T> FindAll();
}
I would extract the code to create the customer into a method. You can call that from your test methods, and if you name it something like
SetUpCustomerForRepositorythen it will provide some documentation about what you are doing.Here is an example based on your sample:
You could also call it from the test set up method, but I actually prefer to do it in the test method so that people looking at the test know what is being set up for the test.
As for your concern about it being modified….if that happens, then your tests will fail, and you’ll know about it.