如何使Mockito调用不同的方法但返回相同的对象示例

ni65a41a  于 2022-11-08  发布在  其他
关注(0)|答案(3)|浏览(203)

我有以下几种方法

//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返回相同的& updated对象(相同的示例)并继续传递到下一个方法调用?
所以重点是我想要一个汽车对象,这个汽车对象会传递给number方法来更新这个汽车对象.

// 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)

有没有办法在这里重复使用相同的对象?

  • 谢谢-谢谢
pkbketx9

pkbketx91#

在这种情况下使用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毫秒内,这对我来说已经足够了。
q35jwt9p

q35jwt9p2#

any(ParamClass.class)一样使用any匹配器。
在您的情况下when(myMethod.washCar(any(Car.class))).thenReturn(wCar);

mqkwyuun

mqkwyuun3#

您可以使用ArgumentCaptor来捕获参数(您的模拟示例pCar),然后在您的测试中使用该值。

@Mock
Car pcar;
@Captor
ArgumentCaptor<Car> carCaptor;

when(myMethod.polishCar(
any(Car.class))).thenReturn(pCar);

 Mockito.verify(car)
.polishCar(carCaptor.capture());

捕获的参数将是pCar,您可以在整个测试中使用它

相关问题