簡體   English   中英

如果Mockito.when(...)。doReturn(...)從Mockito.doAnswer(...)調用,為什么它無法按預期工作

[英]Why Mockito.when(…).doReturn(…) not working as expected if it called from Mockito.doAnswer(…)

我需要測試一種創建Car對象並使用CarDao將其保存在數據庫中的方法。 另一個方法創建了Car對象,但是如果CarDao是模擬的,則car.getUser()返回null而不是正確的User對象。 這是我的代碼。

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在數據庫中“構建和存儲”汽車對象,並“查找”汽車對象(需要User驗證)。 在CarService中,您可以使用CarDao與數據庫一起使用。
首先,如果您測試Handler類,則需要模擬IT OWN依賴關系,這意味着您需要模擬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並驗證測試中的所有內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM