Java 测试入门
Maria Milusheva
Senior Software Engineer
回顾上一课的依赖流:货币兑换应用依赖银行服务器:

无法验证计算,因为汇率本质上不可预测。
Mocking:为在测试中难以直接使用的真实对象创建模拟对象/行为,使测试不依赖外部依赖。
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

回到上一课示例:
public double convertEuroTo(String currency, double amount) {
double rate = this.bank.getRateEuroTo(currency);
return amount * rate;
}
➡ 为测试构造可预测的 EuropeanCentralBankServer 对象
使用 mock 进行测试如下:
@Test void convert_returnsExpectedValue() { EuropeanCentralBankServer bank = mock(EuropeanCentralBankServer.class); ExchangeApp exchangeApp = new ExchangeApp(bank);// 需要为 mock 设定行为 when(bank.getRateEuroTo("USD")).thenReturn(1.1);// 从 mock 对象调用 getRateEuroTo,获得预设值 double result = exchangeApp.convertEuroTo("USD", 1000); assertEquals(1100, result); // 现在可对精确返回值断言 }
务必记得为 mock 设定行为:
@Test
void convert_returnsExpectedValue() {
EuropeanCentralBankServer bank = mock(EuropeanCentralBankServer.class);
ExchangeApp exchangeApp = new ExchangeApp(bank);
// 未设定行为——mock 银行对象不知道如何响应 getRateEuroTo
double result = exchangeApp.convertEuroTo("USD", 1000);
assertEquals(1100, result); // 由于缺少设置将失败
}
测试失败信息:
org.opentest4j.AssertionFailedError:
Expected :1100.0
Actual :0.0
为 mock 预设行为称为存根(stubbing)。
Stubbing:为测试中的调用提供最少、预定义的返回;对未在测试中编程的调用通常不响应。
Mockito 也可模拟错误场景:
EuropeanCentralBankServer bank = mock(EuropeanCentralBankServer.class);
ExchangeApp exchangeApp = new ExchangeApp(bank);
// 使用 thenThrow() 替代 thenReturn()
when(bank.getRateEuroTo("USD"))
.thenThrow(new RuntimeException("Bank server unavailable."));
exchangeApp.convertEuroTo("USD", 1000); // getRateEuroTo 将抛出异常
Java 测试入门