java - 使用 Mockito 测试方法的正确方法是什么?
问题描述
我目前正在尝试使用 Mockito 测试一种方法,但我坚持使用某种方法。
例如,有名为 Car 和 CarSystem 的类。
car 类包含两个参数,Name(String) 和它的 License Plate(String) 以及它们的 getter/setter 方法。
我尝试使用 Mockito 测试的方法是一个名为 addCar 的方法,它位于 CarSystem 类中。
汽车系统类:
private final List<Car> cars= new ArrayList<>();
public Car addCar(String name, String plateNumber) throws IllegalStateException {
Car clash = getCar(plateNumber);
if (null != clash) throw new IllegalStateException("Car with that Number already exists");
Car car = new Car(name, plateNumber);
cars.add(car);
return car;
}
public Car getCar(String match) {
for (Car car: cars) {
if (car.getPlateNumber().equals(match)) return car;
}
return null;
}
我要测试的是两件事:
当汽车列表中已经存在车牌号的汽车时,它会成功抛出 IllegalStateException 异常。
它成功地将汽车添加到列表中。
我只使用 JUnit 所做的是:
@Test
public void testAddCar_ThrowingException() {
try {
CarSystem sys = new CarSystem();
Car car = sys.addCar("1234", "Toyota123");
Car car1= sys.addCar("1234", "Honda123");
Assert.fail();
} catch(IllegalStateException e) {
System.out.println(e);
}
}
@Test
public void testAddCar() {
CarSystem sys = new CarSystem();
Car car = sys.addCar("1234", "Toyota123");
Assert.assertEquals(sys.getCar(1234).getName(), "Toyota123");
}
但我不知道如何使用 Mockito 来测试它们......谁能帮助我或给我一个提示?
PS)我可以自由更改 Mockito 测试的课程内容。
解决方案
我不会创建Car
要添加到方法中的方法,而是将其作为参数传入,即
interface CarService {
Car addCar(Car toAdd);
Car getCar(String plateNumber);
}
由于您正在测试服务本身,因此您无法模拟它 - 只有汽车。由于Car
您访问的唯一数据是getPlateNumber
,因此测试看起来像这样:
class ScratchTest {
private CarService sut;
@Before
public void before() {
sut = new CarService();
}
@Test
public void addSucceeds() {
String plateNumber = "new";
Car toAdd = mock(Car.class);
when(toAdd.getPlateNumber()).thenReturn(plateNumber);
Car added = sut.addCar(toAdd);
// assert return value
assertSame(toAdd, added);
// assert car now available via get
Car stored = sut.getCar(plateNumber);
assertSame(toAdd, stored);
}
@Test(expected = IllegalArgumentException.class)
public void addFails() {
Car existing = mock(Car.class);
String plateNumber = "existing";
when(existing.getPlateNumber()).thenReturn(plateNumber);
sut.addCar(existing);
Car toAdd = mock(Car.class);
when(toAdd.getPlateNumber()).thenReturn(plateNumber);
sut.addCar(toAdd);
}
}
您不能真正独立地测试 add 和 get ,因为它们彼此不变量: 1. 如果add
使用具有新车牌号的汽车调用,则后续get
给定的车牌号将检索它,并且 2.get
使用车牌调用if之前调用过的 aCar
的编号add
,它将被返回。
推荐阅读
- c# - 基于操作系统的不同 NuGet 包
- html - 引导填充面板到行底部
- c# - 如何强制在 .NET Core DI 中创建类的实例?
- docker - 查找 Docker 容器可以从容器内访问多少 CPU
- apache-spark - LoadIncrementalHFiles 不适用于 Hbase 批量加载。扫描返回 0 行
- mysql - 每个组的查询最大 n 具有不同的问题
- java - 两个提交按钮来做两件不同的事情
- android - 在菜单中的抽屉布局选项中包含相对布局后不响应点击
- python - 无论 matplotlib 中箭头的角度如何,使箭头形状对称
- angularjs - AngularJS - 控制器未向 ocLazyLoad 注册