2016-04-28 5 views
1

Ich brauche eine Methode zu testen, die Car Objekt erstellt und CarDao zu speichern verwendet es in der Datenbank. Eine andere Methode wird Car Objekt erstellt, aber wenn CarDao wird dann simuliert null anstelle der richtigen User Objekt zurückgegeben. Das ist mein Code.Warum Mockito.when (...). DoReturn (...) funktioniert nicht wie erwartet, wenn es von 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()); 

Warum carDao.getById(carId).getUser() gibt null zurück? Und was muss ich tun, um das vollständige Objekt mit dem korrekten user Feldwert zu erhalten?

Aktualisiert

carDao Nutzung:

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 

Im Folgenden ist der Teil der CarService Klasse, wo der Code Nullpointer wirft.

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

Danke.

+1

Ist Ihr 'User' Objekt in Ihrem' car' Objekt festgelegt, das Sie aus 'invocationOnMock.getArguments() [0];'? Wenn nicht, muss überprüft werden, warum es null ist – Draken

+0

@Draken, Ja 'User' Objekt wird in dem 'Auto'-Objekt gesetzt, das ich von' invocationOnMock.getArguments() [0]; ' –

+0

abgerufen habe carDao.getById (carId) .getUser() 'Eigenschaft? Können wir Ihre Abteilung sehen, wo das heißt? – Draken

Antwort

2

Wie ich aus dem Beispiel verstehen, haben Sie eine Klasse, die Sie testen möchten, rufen Sie uns Handler. In diesem Handler verwenden Sie CarService, um Auto-Objekt zu "bauen und zu speichern", und Auto-Objekt zu "finden" (mit einigen User überprüfen) in DB. In CarService verwenden Sie CarDao, um mit DB zu arbeiten.
Also zuerst: Wenn Sie Handler-Klasse testen, dann müssen Sie IT-eigene Abhängigkeiten spotten, es bedeutet, dass Sie CarService, aber nicht CarDao in CarService (nicht die zweite Ebene verschachtelter Abhängigkeiten) maskieren müssen. Sie müssen CadDao bei jedem Test von CarService ausprobieren und es sollte vom CarHandlerTest getrennt werden.

Und zweitens: Ich simuliere dein Beispiel und es funktioniert, siehe den Code unten.

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

Und am interessantesten Teil - Test.

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(); 
    } 
} 

Sie können auch Car von foo() Methode zurückzukehren und alles in Test überprüfen.