آشنایی با تست واحد و استفاده از کتابخانه Moq
نویسنده: ارش کریمی
تاریخ: ۱۳۹۳/۰۹/۲۹ ۱۹:۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
/// <summary>
/// حساب بانکی
/// </summary>
public class Account
{
/// <summary>
/// مشتری
/// </summary>
public string Customer { get; set; }
/// <summary>
/// موجودی حساب
/// </summary>
public float Balance { get; set; }
/// <summary>
/// وضعیت
/// </summary>
public bool Active { get; set; }
public Account(string customer, float balance)
{
Customer = customer;
Balance = balance;
Active = true;
}
/// <summary>
/// افزایش موجودی / واریز به حساب
/// </summary>
/// <param name="amount">مبلغ واریز</param>
public void Credit(float amount)
{
if (!Active)
throw new Exception("این حساب مسدود است.");
if (amount < 0)
throw new ArgumentOutOfRangeException("amount");
Balance += amount;
}
/// <summary>
/// کاهش موجودی / برداشت از حساب
/// </summary>
/// <param name="amount">مبلغ برداشت</param>
public void Debit(float amount)
{
if (!Active)
throw new Exception("این حساب مسدود است.");
if (amount < 0)
throw new ArgumentOutOfRangeException("amount");
if (Balance < amount)
throw new ArgumentOutOfRangeException("amount");
Balance -= amount;
}
/// <summary>
/// انسداد / رفع انسداد
/// </summary>
public void ChangeStateAccount()
{
Active = !Active;
}
} class Program
{
static void Main(string[] args)
{
var account = new Account("Ali",1000);
account.Credit(4000);
account.Debit(2000);
Console.WriteLine("Current balance is ${0}", account.Balance);
Console.ReadKey();
}
} [TestClass]
public class UnitTest
{
/// <summary>
/// تعریف حساب جدید و بررسی تمامی فرآیندهای معمول روی حساب
/// </summary>
[TestMethod]
public void Create_New_Account_And_Check_The_Process()
{
//Arrange
var account = new Account("Hassan", 4000);
var account2 = new Account("Ali", 10000);
//Act
account.Credit(5000);
account2.Debit(3000);
account.ChangeStateAccount();
account2.Active = false;
account2.ChangeStateAccount();
//Assert
Assert.AreEqual(account.Balance,9000);
Assert.AreEqual(account2.Balance,7000);
Assert.IsTrue(account2.Active);
Assert.AreEqual(account.Active,false);
} /// <summary>
/// زمانی که کاربر بخواهد به یک حساب مسدود واریز کند باید جلوی آن گرفته شود.
/// </summary>
[TestMethod]
[ExpectedException(typeof (Exception))]
public void When_Deactive_Account_Wants_To_add_Credit_Should_Throw_Exception()
{
//Arrange
var account = new Account("Hassan", 4000) {Active = false};
//Act
account.Credit(4000);
//Assert
//Assert is handled with ExpectedException
}
[TestMethod]
[ExpectedException(typeof (ArgumentOutOfRangeException))]
public void When_Customer_Wants_To_Debit_More_Than_Balance_Should_Throw_ArgumentOutOfRangeException()
{
//Arrange
var account = new Account("Hassan", 4000);
//Act
account.Debit(5000);
//Assert
//Assert is handled with ArgumentOutOfRangeException
} public class OrganizationalService : ICommandHandler<CreateUnitTypeCommand>,
ICommandHandler<DeleteUnitTypeCommand>,
{
private readonly IUnitOfWork _unitOfWork;
private readonly IUnitTypeRepository _unitTypeRepository;
private readonly IOrganizationUnitRepository _organizationUnitRepository;
private readonly IOrganizationUnitDomainService _organizationUnitDomainService;
public OrganizationalService(IUnitOfWork unitOfWork, IUnitTypeRepository unitTypeRepository, IOrganizationUnitRepository organizationUnitRepository, IOrganizationUnitDomainService organizationUnitDomainService)
{
_unitOfWork = unitOfWork;
_unitTypeRepository = unitTypeRepository;
_organizationUnitRepository = organizationUnitRepository;
_organizationUnitDomainService = organizationUnitDomainService;
} [TestClass]
public class OrganizationServiceTest
{
private static OrganizationalService _organizationalService;
private static Mock<IUnitTypeRepository> _mockUnitTypeRepository;
private static Mock<IUnitOfWork> _mockUnitOfWork;
private static Mock<IOrganizationUnitRepository> _mockOrganizationUnitRepository;
private static Mock<IOrganizationUnitDomainService> _mockOrganizationUnitDomainService;
[ClassInitialize]
public static void ClassInit(TestContext context)
{
TestBootstrapper.ConfigureDependencies();
_mockUnitOfWork = new Mock<IUnitOfWork>();
_mockUnitTypeRepository = new Mock<IUnitTypeRepository>();
_mockOrganizationUnitRepository = new Mock<IOrganizationUnitRepository>();
_mockOrganizationUnitDomainService=new Mock<IOrganizationUnitDomainService>();
_organizationalService = new OrganizationalService(_mockUnitOfWork.Object, _mockUnitTypeRepository.Object, _mockOrganizationUnitRepository.Object,_mockOrganizationUnitDomainService.Object);
} /// <summary>
/// یک نوع واحد سازمانی را حذف مینماید
/// </summary>
/// <param name="command"></param>
public void Handle(DeleteUnitTypeCommand command)
{
var unitType = _unitTypeRepository.FindBy(command.UnitTypeId);
if (unitType == null)
throw new DeleteEntityNotFoundException();
ICanDeleteUnitTypeSpecification canDeleteUnitType = new CanDeleteUnitTypeSpecification(_organizationUnitRepository);
if (canDeleteUnitType.IsSatisfiedBy(unitType))
throw new UnitTypeIsUnderUsingException(unitType.Title);
_unitTypeRepository.Remove(unitType);
} /// <summary>
/// کامند حذف نوع واحد سازمانی باید به درستی حذف کند.
/// </summary>
[TestMethod]
public void DeleteUnitTypeCommand_Should_Delete_UnitType()
{
//Arrange
var unitTypeId=new Guid();
var deleteUnitTypeCommand = new DeleteUnitTypeCommand { UnitTypeId = unitTypeId };
var unitType = new UnitType("خوشه");
var org = new List<OrganizationUnit>();
_mockUnitTypeRepository.Setup(d => d.FindBy(deleteUnitTypeCommand.UnitTypeId)).Returns(unitType);
_mockUnitTypeRepository.Setup(x => x.Remove(unitType));
_mockOrganizationUnitRepository.Setup(z => z.FindBy(unitType)).Returns(org);
try
{
//Act
_organizationalService.Handle(deleteUnitTypeCommand);
}
catch (Exception ex)
{
//Assert
Assert.Fail(ex.Message);
}
} /// <summary>
/// کامند حذف یک نوع واحد سازمانی باید پیش از حذف بررسی کند که این شناسه داده شده برای حذف موجود باشد.
/// </summary>
[TestMethod]
[ExpectedException(typeof(DeleteEntityNotFoundException))]
public void DeleteUnitTypeCommand_ShouldNot_Delete_When_UnitTypeId_NotExist()
{
//Arrange
var unitTypeId = new Guid();
var deleteUnitTypeCommand = new DeleteUnitTypeCommand();
var unitType = new UnitType("خوشه");
var org = new List<OrganizationUnit>();
_mockUnitTypeRepository.Setup(d => d.FindBy(unitTypeId)).Returns(unitType);
_mockUnitTypeRepository.Setup(x => x.Remove(unitType));
_mockOrganizationUnitRepository.Setup(z => z.FindBy(unitType)).Returns(org);
//Act
_organizationalService.Handle(deleteUnitTypeCommand);
}
/// <summary>
/// کامند حذف یک نوع واحد سازمانی نباید اجرا شود وقتی که نوع واحد برای تعریف واحدهای سازمان استفاده شده است.
/// </summary>
[TestMethod]
[ExpectedException(typeof(UnitTypeIsUnderUsingException))]
public void DeleteUnitTypeCommand_ShouldNot_Delete_When_UnitType_Exist_but_UsedForDefineOrganizationUnit()
{
//Arrange
var unitTypeId = new Guid();
var deleteUnitTypeCommand = new DeleteUnitTypeCommand { UnitTypeId = unitTypeId };
var unitType = new UnitType("خوشه");
var org = new List<OrganizationUnit>()
{
new OrganizationUnit("مدیریت یک", unitType, null),
new OrganizationUnit("مدیریت دو", unitType, null)
};
_mockUnitTypeRepository.Setup(d => d.FindBy(deleteUnitTypeCommand.UnitTypeId)).Returns(unitType);
_mockUnitTypeRepository.Setup(x => x.Remove(unitType));
_mockOrganizationUnitRepository.Setup(z => z.FindBy(unitType)).Returns(org);
//Act
_organizationalService.Handle(deleteUnitTypeCommand);
}