我试图找出如何在while循环语句中检查在某个迭代点打印出的系统。
我有这个方法:
Searching for binary rubies, this might take some time.
No binary rubies available for: ubuntu/14.04/i386/ruby-2.4.0.
Continuing with compilation. Please read 'rvm help mount' to get more information on binary rubies.
Checking requirements for ubuntu.
Requirements installation successful.
Installing Ruby from source to: /home/aniket/.rvm/rubies/ruby-2.4.0, this may take a while depending on your cpu(s)...
ruby-2.4.0 - #downloading ruby-2.4.0, this may take a while depending on your connection...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- 0:00:01 --:--:-- 0
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: http://curl.haxx.se/docs/sslcerts.html
curl performs SSL certificate verification by default, using a "bundle"
of Certificate Authority (CA) public keys (CA certs). If the default
bundle file isn't adequate, you can specify an alternate file
using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
the bundle, the certificate verification probably failed due to a
problem with the certificate (it might be expired, or the name might
not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
the -k (or --insecure) option.
/home/aniket/.rvm/scripts/fetch: line 105: log: command not found
Checking fallback: https://ftp.ruby-lang.org/pub/ruby/2.4/ruby-2.4.0.tar.bz2
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- 0:00:02 --:--:-- 0
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: http://curl.haxx.se/docs/sslcerts.html
curl performs SSL certificate verification by default, using a "bundle"
of Certificate Authority (CA) public keys (CA certs). If the default
bundle file isn't adequate, you can specify an alternate file
using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
the bundle, the certificate verification probably failed due to a
problem with the certificate (it might be expired, or the name might
not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
the -k (or --insecure) option.
/home/aniket/.rvm/scripts/fetch: line 105: log: command not found
Failed download
There has been an error fetching the ruby interpreter. Halting the installation.
JUnit的:
/**
* 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;
}
所以我想明确的是,如果用户插入1欧元,他仍然需要多插入半欧元。
答案 0 :(得分:3)
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);
}
。它不应该
逻辑和渲染任务是两个截然不同的事情
混合这两项职责违反了单一责任原则(更改课程的原因不止一个)。
此外,它可以防止像你的情况一样测试方法的核心逻辑
这里:
....
CountMoney countMoney = null;
...
if(change > 0) {
countMoney = new CountMoney(makeCoffeeText, sessionMoney, change);
}
else {
countMoney = new CountMoney(makeCoffeeText, sessionMoney);
}
...
return countMoney;
您应该创建一个包含所有这些数据的自定义类的实例,并返回它而不是String。
例如:
CountMoney countMoneyForCupSize()
在调用String renderingCountMoney(CountMoney countMoney)
的应用代码中,您可以调用执行渲染的渲染方法(位于渲染类中),例如:countMoneyForCupSize()
。
通过这种方式,您的设计会更好(每个类和每个方法都有明确的职责),您可以单独测试template <typename T>
struct function_traits { .... some code ..... }
,而无需考虑用户文本呈现。
答案 1 :(得分:2)
您可以直接检查多次调用insertCash
。一种方法是使用thenReturn模拟对insertCash
的多次调用:
when(machineSpy.insertCash()).thenReturn(1.0, 0.5);
之后你可以verify insertCash
被称为两次:
verify(machineSpy, times(2)).insertCash();
verifyNoMoreInteractions(machineSpy);
查看此问题以获取其他选项:
如果您仍想捕获并测试输出到System.out,则需要重定向标准输出。早先的问题已经涵盖了这一点: