我试图找出如何在while循环语句中的某个迭代点上打印出哪个系统。
我有这种方法:
/**
* This method counts how much money user inserted
* If it is not enough to buy chosen cup size it asks user to insert more
* Otherwise it checks if user does not need the change
* and collects money to machine based on cup size price
* This method gets the message from properties file by key identifies
* add.more.money - if not enough money is in machine
* user.paid.change - if user put too much to machine
* user.paid - if user paid the exact amount of money
* @param constantPrice - cup size price
* @return countMoney - how much user put to machine
*/
@Override
public String countMoneyForCupSize(double constantPrice) {
// constant - price depending on cup size
String countMoney = " ";
double sessionMoney = 0;
boolean flag = true;
while(flag) {
if(constantPrice > sessionMoney) {
System.out.println(MessageFormat.format(prop.getProperty("add.more.money"), (constantPrice-sessionMoney)));
double insertedCash;
try {
insertedCash = insertCash();
sessionMoney = sessionMoney + insertedCash;
if(insertedCash == 0) {
System.out.println(MessageFormat.format(prop.getProperty("end.procedure"), sessionMoney));
flag = false;
}
} catch (InvalidCoinException e) {
System.out.println(e.getMessage());
}
}
else {
double change = sessionMoney - constantPrice;
String makeCoffeeText = makeCoffee();
if(change > 0) {
countMoney = MessageFormat.format(prop.getProperty("user.paid.change"), makeCoffeeText, sessionMoney, change);
}
else {
countMoney = MessageFormat.format(prop.getProperty("user.paid"), makeCoffeeText, sessionMoney);
}
collectMoney(constantPrice);
flag = false;
}
}
return countMoney;
}
JUnit:
@org.junit.Rule
public final ProvideSystemProperty property1 = new ProvideSystemProperty("MoreEuro", "You need more: 0.5 euro");
@org.junit.Test
public void testCountMoneyForCupSize() {
System.out.println("---------------- Count Money For Cup Size -----------------");
double largePrice = 1.5;
double mediumPrice = 1;
double smallPrice = 0.75;
try {
when(machineSpy.insertCash()).thenReturn(1.0);
assertEquals(machineSpy.countMoneyForCupSize(largePrice), System.getProperty("MoreEuro"));
} catch (InvalidCoinException e) {
System.out.println(e.getMessage());
}
}
因此,我想明确指出,如果用户插入1欧元,他仍需要再插入半欧元。
最佳答案
1)when(machineSpy.insertCash()).thenReturn(1.0);
模拟被测试的公共方法调用的私有方法不一定是一件好事,因为您应该模拟依赖关系,而不是模拟被测对象的行为。如果insertCash()
具有某些必须被嘲笑的特性,则您可能应该移至另一个类中。
2)关于:
如何在迭代的某个点中断循环并检查哪个系统
打印出来
为什么不仅仅执行break
指令?
3)machineSpy.countMoneyForCupSize(largePrice);
因此,我想明确指出,如果用户插入1欧元。他仍然需要
多插入一半欧元
我认为您应该更改countMoneyForCupSize(double)
的约定,而不是尝试测试在控制台中编写的并没有真正测试方法行为的输出。
在您的实际版本中,该方法返回格式化的String
。它不应该。
逻辑和渲染任务是两件截然不同的事情。
将两种职责混合在一起违反了“单一职责”原则(改变班级的一个以上原因)。
此外,这可能会阻止您测试方法的核心逻辑
这里 :
if(change > 0) {
countMoney = MessageFormat.format(prop.getProperty("user.paid.change"), makeCoffeeText, sessionMoney, change);
}
else {
countMoney = MessageFormat.format(prop.getProperty("user.paid"), makeCoffeeText, sessionMoney);
}
您应该创建一个包含所有这些数据的自定义类的实例,然后返回它而不是String。
例如 :
....
CountMoney countMoney = null;
...
if(change > 0) {
countMoney = new CountMoney(makeCoffeeText, sessionMoney, change);
}
else {
countMoney = new CountMoney(makeCoffeeText, sessionMoney);
}
...
return countMoney;
然后,在调用
CountMoney countMoneyForCupSize()
的应用程序代码中,您可以调用执行渲染的渲染方法(位于渲染类中),例如:String renderingCountMoney(CountMoney countMoney)
。这样,您的设计会更好(每个类和每个方法都有明确定义的职责),并且可以在不考虑用户文本呈现的情况下对
countMoneyForCupSize()
进行单元测试。