2016-04-28 16 views
1

Carオブジェクトを作成し、CarDaoを保存するメソッドをテストする必要がありますそれはデータベースにあります。別の方法ではCarオブジェクトが作成されますが、CarDaoが模擬の場合は、car.getUser()Userオブジェクトの代わりにnullオブジェクトを返します。これは私のコードです。Mockito.when(...)。doReturn(...)がMockito.doAnswer(...)から呼び出されたときに期待通りに機能しない理由

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 

コードがNullPointerExceptionがスローCarServiceクラスの一部です。

// 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; 
} 

ありがとうございます。

+1

あなたの 'car'オブジェクトは' invocationOnMock.getArguments()[0]; 'から取得したものですか?そうでない場合は、なぜそれがnullであるかを確認する必要があります – Draken

+0

@Draken、Yes '' ''オブジェクトは '' invocationOnMock.getArguments()[0];から取得した 'car'オブジェクトに設定されます –

+0

' carDao.getById(carId).getUser() 'プロパティ?それが呼ばれているあなたのセクションを見ることができますか? – Draken

答えて

2

私が理解しているように、テストしたいクラスがありますので、Handlerと呼んでください。このハンドラでは、車オブジェクトを "構築して保存する"にはCarServiceを使用し、DBには車オブジェクトを(一部ではUserで)検索します。 CarServiceでは、CarDaoを使用してDBを操作します。
まず、Handlerクラスをテストすると、IT OWNの依存関係をモックする必要があります。つまり、CarServiceをモックする必要がありますが、CarServiceはCarServiceの中ではネストされた依存関係の第2レベルではありません。 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を返すと、テストのすべてを確認することができます。

関連する問題