我有以下方法
//my method
public Car polishCar(Car car){
car.setPolish(true);
car.setPolishDate(new Date());
return car;
}
//myMethod
public Car washCar(Car car){
car.setWash(true);
car.setWashDate(new Date());
return car;
}
// mainMethod
public Car serviceCar(){
Car car = new Car();
myMethod.polishCar(car);
myMethod.washCar(car);
......
return Car;
}
这是我用mockito进行单元测试的代码,我需要创建2个不同的Car对象,这些对象看起来是冗余的,并不断向其添加新值。
Car pCar = new Car();
pCar.setPolish(true);
pCar.setPolishDate(new Date());
//first call
when(myMethod.polishCar(any(Car.class))).thenReturn(pCar);
Car wCar = new Car();
wCar.setPolish(true);
wCar.setPolishDate(new Date());
wCar.setWash(true);
wCar.setWashDate(new Date());
//second call with same car object from previous, and return same car object with additional value
when(myMethod.washCar(eq(pCar))).thenReturn(wCar);
Car testCar = mainMethod.serviceCar();
// check if they are same instance
assertEquals(testCar, wCar);
assertEquals("true", wCar.getWash());
assertEquals("true", wCar.polish());
我怎样才能更好地处理这种情况,使mockito返回相同的&更新对象(相同的实例),并继续传递到下一个方法调用?
所以重点是我想要有一个car对象这个car对象将传递给number方法来更新这个car对象
// Create 1 car object
Car singleCar = new Car();
//pass to first method, and return singleCar with updated polish & polishDate
when(myMethod.polishCar(eq(singleCar))).thenReturn(singleCar);
//pass to second method, and return singleCar with updated wash and washDate
when(myMethod.washCar(eq(singleCar))).thenReturn(singleCar);
// call main method for testing
Car testCar = mainMethod.serviceCar();
// assert testCar == singleCar
// assert singleCar is updated (wash == true & polish == true)
是否有办法在这里重用相同的对象?
谢谢。
在这种情况下使用mock是没有意义的。只要造出一辆真正的SUT和一辆真正的车。只需调用真实汽车实例的测试方法,直接验证汽车的状态。
@Test
public polishAndCarTest(){
Car car = new Car();
Date now = new Date();
sut.polishCar(car);
sut.washCar(car);
assertThat(car.isPolish()).isTrue();
assertThat(car.getPolishDate()).isCloseTo(now,2);
assertThat(car.isWash()).isTrue();
assertThat(car.getWashDate()).isCloseTo(now,2);
}
指出:
最好重构
polishCar()
和washCar()
,使其可以接受给定的日期作为输入参数,而不是硬编码为当前时间。之后,当在测试用例中调用这些方法时,您可以通过一个测试日期,并且可以很容易地验证抛光日期和清洗日期是否真的更新到这个日期。如果你不喜欢这个,你可以使用assertj来验证这些日期在
polishCar()
/washCar()
被调用后的时刻接近2毫秒,这对我来说已经足够好了。
像any(ParamClass.class)
一样使用any
匹配器
when(myMethod.washCar(any(Car.class))).thenReturn(wCar);
您可以使用ArgumentCaptor捕获参数(您的模拟实例pCar)。然后在测试中使用该值。下面是伪代码,但本质上是参数捕获器的工作方式
@Mock
Car pcar;
@Captor
ArgumentCaptor<Car> carCaptor;
when(myMethod.polishCar(
any(Car.class))).thenReturn(pCar);
Mockito.verify(car)
.polishCar(carCaptor.capture());
捕获的参数将是pCar,然后您可以在整个测试中使用它