我正在尝试测试我的方法,该方法使用扫描仪对象和用户键盘的动态输入。我无法想出一种方法来测试它。问题是我想要使用的方法也用在另一个方法的循环中。我认为Mockito
在这种特殊情况下会派上用场,不幸的是,我找不到如何测试它的方法。如果该特定方法试图返回错误的值,则会抛出异常。那么,代码将提供更深入的解释(我希望)。
/**
* This method asks user to insert cash
* It gets the property text from properties file by key insert.cash
* Checks if coin is in proper format
* Checks if coin exists in available coins array
* Otherwise throws exception
* @throws InvalidCoinException
* @return cash - how much money user inserted
*/
@Override
public double insertCash() throws InvalidCoinException {
double cash = 0;
double temp; // temporary variable which goes through all if statems if all conditions are satisfied it gets assigned to cash variable
boolean coinExists = false;
System.out.println(prop.getProperty("insert.cash"));
if(!sc.hasNextDouble()) {
throw new InvalidCoinException(MessageFormat.format(prop.getProperty("invalid.coin"), sc.next()));
}
else {
temp = sc.nextDouble();
for(int i = 0; i < availableCoins.length; i++) {
if(temp == availableCoins[i] || temp == 0) {
coinExists = true;
}
}
if(coinExists == true) {
cash = temp;
}
else {
throw new InvalidCoinException(MessageFormat.format(prop.getProperty("invalid.coin"), temp));
}
}
return cash;
}
JUNIT:
@org.junit.Before
public void initializeTest() throws IOException {
machine = new CoffeeMachineImplementation();
machineSpy = Mockito.spy(CoffeeMachineImplementation.class);
}
@org.junit.Test
public void testInsertCash() throws InvalidCoinException {
System.out.println("---------------- Insert cash -----------------");
Double input2 = 0.06;
Double input3 = 200.0;
Double input4 = 0.02;
try {
when(machineSpy.insertCash()).thenReturn(input2)
.thenThrow(new InvalidCoinException("..."));
fail("Should have thrown an exception " + input2);
}
catch (InvalidCoinException e) {
String exception = "Invalid coin: " + input2 + " euro is not existing coin";
System.out.println(e.getMessage());
assertEquals(exception, e.getMessage());
}
我的扫描仪对象在构造函数中声明(因为不仅一种方法使用扫描程序):
public CoffeeMachineImplementation() throws IOException {
prop = new Properties();
input = new FileInputStream("src/localization.properties");
maWaterCap = 5;
maCoffeeCap = 3;
prop.load(input);
sc = new Scanner(System.in);
}
答案 0 :(得分:1)
在这种情况下似乎没有意义......
我会更改类如下:
a)启用扫描仪模拟注入
b)模拟异常消息创建以避免调用任何外部资源
Impl Class
public CoffeeMachineImplementation() throws IOException {
maWaterCap = 5;
maCoffeeCap = 3;
setScannerInstance(new Scanner(System.in));
}
void setScannerInstance(Scanner s){
this.sc = sc;
}
String getExceptionMessage(String propKey, Double value){
return MessageFormat.format(prop.getProperty(propKey), value);
}
Properties getProperties(){
if(prop == null){
prop = new Properties();
input = new FileInputStream("src/localization.properties");
prop.load(input);
}
return prop;
}
public double insertCash() throws InvalidCoinException {
double cash = 0;
double temp; // temporary variable which goes through all if statems if all conditions are satisfied it gets assigned to cash variable
boolean coinExists = false;
System.out.println(getProperties().getProperty("insert.cash"));
if(!sc.hasNextDouble()) {
throw new InvalidCoinException(getExceptionMessage("invalid.coin", sc.next()));
}
测试类
由于扫描仪属于最终类...... PowerMockito 应该使用(example)
@RunWith(PowerMockRunner.class)
@PrepareForTest(Scanner.class)
class CoffeeMachineImplementationTest{
@org.junit.Before
public void initializeTest() throws IOException {
machine = new CoffeeMachineImplementation();
machineSpy = Mockito.spy(CoffeeMachineImplementation.class);
doReturn(new Properties()).when(machineSpy).getProperties();
}
@org.junit.Test
public void shouldThrowException_whenNoNextDouble() throws InvalidCoinException {
Double input = 0.06;
String expectedMessage = "expectedMessage";
Scanner scMock = PowerMock.createMock(Scanner.class)
machineSpy.setScannerInstance(scMock);
when(scMock.hasNextDouble()).thenReturn(false);
when(scMock.next()).thenReturn(input);
doReturn(expectedMessage).when(machineSpy)
.getExceptionMessage("invalid.coin", input);
try {
machineSpy.insertCash();
}
catch (InvalidCoinException e) {
assertEquals(expectedMessage, e.getMessage());
}
最重要的是,您应该尝试在各种测试情况下模拟扫描器类,然后正常调用insertCash()
..并期望某些行为。