public void ShouldRateDataConsumptionWithReducedDataRating() { //Arrange //TODO: avoid code duplication in tests decimal reductionFactor = (decimal)0.5; var callerNumber = new PhoneNumber("4530131514"); var receiverNumber = new PhoneNumber("4530202020"); var startTime = new DateTime(2014, 1, 9, 21, 10, 10); var endTime = new DateTime(2014, 1, 9, 21, 20, 20); var subscriptionId = new SubscriptionId(new Guid("b8e5bae2-76e7-49a8-b5ae-2cd0eb229b16")); var dataConsumption = new DataConsumption(callerNumber, new Amount(30.0, Unit.MB), 1, startTime, subscriptionId); var reducedDataRating = new ReducedDataRatingDecorator(new DataRating((decimal)3), reductionFactor); //Act var result = reducedDataRating.Rate(dataConsumption); //Assert Assert.Equal(30 * 3 * reductionFactor, result); }
/// <summary> /// Robert Martin actually suggests to put error handling in another method. Lets do that. /// </summary> /// <param name="consumption"></param> /// <returns></returns> public override decimal Rate(Consumption consumption) { if (!(consumption is DataConsumption)) { throw new ArgumentException("consumption has to be of type DataConsumption", "consumption"); } DataConsumption dataConsumption = (DataConsumption)consumption; try{ return(DivideConsumptionByUnitSizeAndMultiplyWithUnitPrice(dataConsumption)); } catch (DivideByZeroException dbze) { //handle specífic exception here. (We have actually guarded against UnitSize being zero. throw dbze; } catch (Exception ex) // We might consider narrowing the scope of exceptions { //TODO: log exception, or handle it or just rethrow it. throw ex; } }
/// <summary> /// Errorhandling is handled in calling method /// </summary> /// <param name="dataConsumption"></param> /// <returns></returns> protected decimal DivideConsumptionByUnitSizeAndMultiplyWithUnitPrice(DataConsumption dataConsumption) { var result = ((decimal)dataConsumption.Amount.Value / dataConsumption.UnitSize) * UnitPrice; return(result); }