gpt4 book ai didi

java - 如果从 Mockito.doAnswer(...) 调用,为什么 Mockito.when(...).doReturn(...) 不能按预期工作

转载 作者:行者123 更新时间:2023-11-30 02:57:11 25 4
gpt4 key购买 nike

我需要测试一种创建 Car 对象并使用 CarDao 将其保存在数据库中的方法。另一种方法创建 Car 对象,但如果 CarDao 是模拟的,则 car.getUser() 返回 null 而不是正确的用户对象。这是我的代码。

Mockito.doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocationOnMock) throws Throwable {
lastCarId++;
Car car = (Car) invocationOnMock.getArguments()[0];
// here car.getUser() returns correct user object
car.setId(lastCarId);
Mockito.when(carDao.getById(car.getId())).thenReturn(car);
return null;
}
}).when(carDao).persist(Mockito.any());

为什么carDao.getById(carId).getUser()返回null?我需要做什么才能获得具有正确 user 字段值的完整对象?

已更新

carDao 用法:

Car car = carService.create("car name1", "color", "year", user); // in this method called carDao.persist(...);
car.setColor("color2");
carService.findById(car.getId());
// this method calls carDao.getById(carId)
// and comapres with authenticated user ID.
// But carDao.getById(carId) returns car with user == null

下面是 CarService 类的一部分,其中代码抛出 NullPointerException。

// carService.findById(...) method
public Car findById(Car id) {
Car car = carDao.getById(id);
User carUser = car.getUser(); // returns null
User currentUser = accountService.getAuthenticatedUser(); // returns correct user object
if (!carUser.getId().equals(currentUser.getId())) { // throws NullPointerException
return null;
}
return car;
}

谢谢。

最佳答案

据我从示例中了解到,您有一些要测试的类,我们将其称为Handler。在此处理程序中,您使用 CarService 来“构建和存储”汽车对象,并在数据库中“查找”汽车对象(通过一些用户验证)。在 CarService 中,您使用 CarDao 来处理数据库。
所以首先:如果你测试 Handler 类,那么你需要模拟 IT 自己的依赖项,这意味着你需要模拟 CarService,而不是 CarService 中的 CarDao(不是第二层嵌套依赖项)。每次测试CarService时都需要模拟CadDao,并且应该将测试与CarHandlerTest分开。

第二:我模拟了您的示例并且它有效,请参阅下面的代码。

public class User {} //simple user just to verify not null

public class Car {
private Long id;
private User user;
//getters ans setters
}

public class CarDao { //with stub methods because we will mock it
public void persist(Car car) {}
public Car getById(Long id) {return new Car();}
}

public class CarHandler {
private CarService carService; //with setter
public void foo() { // we will test this method
User user = new User(); //it's like your example but without additional fields (like color)
Car car = carService.create(user); // here we build and store new car
Car sameCar = carService.findById(car.getId());
assert car == sameCar;
}
}

public class CarService {
private CarDao carDao; //with setter
public Car create(User user) {
Car car = new Car();
car.setUser(user);
carDao.persist(car); //here car should get id
return car;
}

public Car findById(Long id) {
Car car = carDao.getById(id);
User user = car.getUser(); //this user should be not null in test
assert user != null; //this assert for verify user
return car;
}
}

最有趣的部分 - 测试。

public class CarHandlerTest {
static long lastCarId = 5;
private CarHandler carHandler = new CarHandler();
private CarService carService = new CarService();
private CarDao carDao;

@Test
public void testFoo() throws Exception {
carDao = Mockito.mock(CarDao.class);
carService.setCarDao(carDao);
carHandler.setCarService(carService);

Mockito.doAnswer(new Answer<Void>() { //I copy it from your example
@Override
public Void answer(InvocationOnMock invocationOnMock) throws Throwable {
lastCarId++;
Car car = (Car) invocationOnMock.getArguments()[0];
// here car.getUser() returns correct user object
car.setId(lastCarId);
Mockito.when(carDao.getById(car.getId())).thenReturn(car);
return null;
}
}).when(carDao).persist(Mockito.any());

carHandler.foo();
}
}

您还可以从 foo() 方法返回 Car 并验证测试中的所有内容。

关于java - 如果从 Mockito.doAnswer(...) 调用,为什么 Mockito.when(...).doReturn(...) 不能按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36907896/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com