Here is a business
Object – TulipBusiness, which has a method to get yearly sales figure
Abstract Type – Interface
public interface ITulipBusiness
{
decimal GetTulipAnnualSales(int year);
}
Concreate Class
public class TulipBusiness : ITulipBusiness
{
ITulipRepository _tulipRepository;
public TulipBusiness(ITulipRepository
tulipRepository)
{
_tulipRepository
= tulipRepository;
}
public decimal GetTulipAnnualSales(int year)
{
decimal salesAmount =
_tulipRepository.GetTulipYearSales(year);
if(salesAmount == 0)
{
throw new Exception("No Sales Found");
}
return salesAmount;
}
}
In above class, we
can see business object depends on repository object to make database call and
get yearly sales figure.
As per DI rule,
the dependency ‘TulipRepository’ should
be abstract and replaced by interface ‘ITulipRepository’
Abstract Type – Interface
public interface ITulipRepository
{
decimal GetTulipYearSales(int year);
decimal GetTulipMonthlySales(int year);
}
Concreate Class
public class TulipRepository : ITulipRepository
{
public decimal GetTulipMonthlySales(int year)
{
throw new NotImplementedException();
}
public decimal GetTulipYearSales(int year)
{
throw new NotImplementedException();
}
}
TulipRepository repository class will be responsible to make database call and get
yearly sales figure but it is not implemented yet.
But if you see business
class, the dependency
of TulipBusiness class is already replaced by interface ITulipRepository and now can easily code
the business object based on ITulipRepository
type and with help of Moq framework, we can easily mock the repository class
behavior and write the unit test for business class.
Here are few basic unit tests of Business class
[TestClass]
public class TulipBusinessTest
{
TulipBusiness business;
Mock _repository;
[TestInitialize]
public void init()
{
_repository = new Mock(MockBehavior.Strict);
// Mocking Repository Class Methods
_repository.Setup(x => x.GetTulipYearSales(2014)).Returns(1050.0M);
_repository.Setup(x => x.GetTulipYearSales(2015)).Returns(1250.0M);
// For 2016 Years, No Sales
_repository.Setup(x => x.GetTulipYearSales(2016)).Returns(0);
// Initlize the business object and inject mocked repostory object
through constructor
business = new TulipBusiness(_repository.Object);
}
[TestMethod]
public void GetTulipSales_20014()
{
decimal result =
business.GetTulipAnnualSales(2014);
// expected value, as per mock should be 1050.0M
Assert.AreEqual(result, 1050.0M);
}
[TestMethod]
public void GetTulipSales_20015()
{
decimal result =
business.GetTulipAnnualSales(2015);
// expected value, as per mock should be 1250.0M
Assert.AreEqual(result, 1250.0M);
}
[TestMethod]
public void GetTulipSales_2016()
{
// expecting Exception
Assert.ThrowsException<Exception>(() =>
business.GetTulipAnnualSales(2016));
}
}
In above unit test
for business class TulipBusiness, Moq framework is allowed us to create the
mimic behavior of Repository object.
Example:
_repository = new Mock(MockBehavior.Strict);
_repository.Setup(x
=> x.GetTulipYearSales(2014)).Returns(1050.0M);
GetTulipYearSales
method of ITulipRepository repository type is mocked and it always return
1050.0 sales figure, when we pass year as 2014 and in this way we can easily
write the unit test and run the unit test without making any database call.
Here is unit test result: