public AcuCafeTests() { mockDrinkFactory = mockRepository.Create <IDrinkFactory>(); mockPreparer = mockRepository.Create <IPreparer>(); mockLogger = mockRepository.Create <IOutputter>(); AcuCafe = new AcuCafe.AcuCafe(mockDrinkFactory.Object, mockPreparer.Object, mockLogger.Object); }
// Added default values for hasCondiment arguments for backwards-compatability. public static Drink OrderDrink(string type, bool hasMilk = false, bool hasSugar = false, bool hasChocolate = false) { Drink drink = null; try { // Rather than explicitly linking the string to Drink requested, use the typename. // Approach like this means we can simply create a new Drink type in AcuCafe.Drinks namespace. Type drinkType = Type.GetType("AcuCafe.Drinks." + type); drink = (Drink)Activator.CreateInstance(drinkType); } catch (Exception ex) { // Throw an error with message back in the case where the type entered doesn't match a drink that is actually served. ServiceLocatorWrapper.ServiceLocator.GetConsoleService().WriteLine(string.Format("We do not serve {0}.", type)); // Throw the exception to the caller. This is intended to give the "waiter" the opportunity to handle the error. Perhaps prompting customer for details of a new order. throw new Exception("Invalid Drink Type supplied."); } // Reworked how condiments are included in a drink for ease of extension. Rather than using an ever growing list of flags, concatenate to a list. // Now, we no longer have to add a new flag for new condiments. // Ideally, I would prefer to have modified the signature of the OrderDrink method to take a list of condiments/names, but maintained for backwards compatability. if (hasMilk) { drink.ExtraCondiments.Add(new Milk()); } if (hasSugar) { drink.ExtraCondiments.Add(new Sugar()); } if (hasChocolate) { drink.ExtraCondiments.Add(new Chocolate()); } try { AcuCafe.Prepare(drink); } catch (Exception ex) { // using service locator pattern here to enable dependency injection of the console in order to unit test output. ServiceLocatorWrapper.ServiceLocator.GetConsoleService().WriteLine("We are unable to prepare your drink."); ServiceLocatorWrapper.ServiceLocator.GetFileService().WriteTextToPath(@"c:\Error.txt", ex.ToString()); // Throw the exception to the caller. The "Waiter" can then handle it. throw ex; } return(drink); }
public static IDrink OrderDrink(string type, bool hasMilk, bool hasSugar) { AcuCafe cafe = new AcuCafe(new DrinkFactory(), new DrinkIngredientFactory(), new BaristaInformer(), new Logger(@"c:\Error.txt")); List <string> ingredients = new List <string>(); if (hasMilk) { ingredients.Add("milk"); } if (hasSugar) { ingredients.Add("sugar"); } return(cafe.OrderDrink(type, ingredients)); }
public static void Prepare(Drink drink) { AcuCafe.ValidateOrder(drink); string message = "We are preparing the following drink for you: " + drink.Description; // I have made this generic for each condiment. So no changes should be required here in future whenever new condiments are added. // Also makes use of the validation setup to ensure we only mention condiments that are relevant to the drink in question. foreach (Type condiment in drink.ValidCondiments.OrderBy(c => c.Name)) { if (drink.ExtraCondiments.Where(ec => ec.GetType().Name == condiment.Name).Any()) { message += ", with " + condiment.Name; } else { message += ", without " + condiment.Name; } } ServiceLocatorWrapper.ServiceLocator.GetConsoleService().WriteLine(message); }
public void OrderDrink_Should_Validate_And_Prepare_Order(bool validation, bool returnNullValidator, bool returnNullDrink, string expectedMessage, Mock <Drink> expectedDrink, [Frozen] Mock <IDrinkFactory> drinkFactory, [Frozen] Mock <IDrinkValidatorFactory> drinkValidatorFactory, [Frozen] Mock <IDrinkValidator> drinkValidator, AcuCafe.AcuCafe sut) { if (!returnNullValidator) { drinkValidatorFactory.Setup(x => x.Get(It.IsAny <string>())).Returns(drinkValidator.Object); drinkValidator.Setup(x => x.Validate(It.IsAny <string>(), It.IsAny <bool>(), It.IsAny <bool>(), It.IsAny <Topping>())).Returns(validation); } else { drinkValidatorFactory.Setup(x => x.Get(It.IsAny <string>())).Returns(default(IDrinkValidator)); } if (!returnNullDrink) { drinkFactory.Setup(x => x.Get(It.IsAny <string>(), It.IsAny <bool>(), It.IsAny <bool>(), It.IsAny <Topping>())).Returns(expectedDrink.Object); expectedDrink.Setup(x => x.Prepare()).Returns(expectedMessage); } else { drinkFactory.Setup(x => x.Get(It.IsAny <string>(), It.IsAny <bool>(), It.IsAny <bool>(), It.IsAny <Topping>())).Returns(default(Drink)); } var result = sut.OrderDrink(It.IsAny <string>(), It.IsAny <bool>(), It.IsAny <bool>()); result.Item1.ShouldBe(expectedMessage); if (!returnNullDrink && !returnNullValidator) { result.Item2.ShouldNotBeNull(); } else { result.Item2.ShouldBeNull(); } }