2015-10-17 76 views
0

我正在尝试使用when .... then mockito的功能。而且我想知道是否有可能为当时的部分放置一个列表,但它是否遍历列表并返回一个不同的对象。所以如果我有一个包含3个对象的列表:A,B,CJUnit Mockito when ... then from array of objects

我希望能够遍历列表并返回列表中的下一个对象。因此,如果在被称为3倍,它第一次将返回A,第二时间B内的方法,也是第三次C.这是我当前的代码:

public class fooTest { 
    private Foo foo; 
    private List<Car> cars; 
    private TestHelper helper; 
    @Mock 
    private DomainService service; 
    private Car car; 

    @Before 
    public void setUp() throws Exception { 
     MockitoAnnotations.initMocks(this);  
     foo = new Foo(); 
     helper = new TestHelper(); 
     cars = new ArrayList<Car>(); 
     Mockito.when(service.findObjectByID(any())).thenAnswer(AdditionalAnswers.returnsElementsOf(cars)); 
    } 

    @Test 
    public void testVin() { 
     cars = helper.generateCars(5, /*random number*/); 
     Fleet result = foo.setFleet(Arrays.asList(helper.makeCars(3)); 
     assertEquals(/*list of numbers*/, result.getCars().getVINs()); 
    } 
} 

public class TestHelper { 
    public Fleet makeCars(int numCars) { 
     Fleet fleet = new Fleet(); 
     Car car; 
     for(int i=0; i<numCars; i++) { 
      car = new Car(i, /*some vin number*/); 
      fleet.add(car); 
     }  

     return fleet; 
    } 
    public List<Car> generateCars(int numCars, int vinNum) { 
     //implementation 
    } 
} 

public class Foo { 
    private DomainService domainService; 

    // Constructor to initialize 

    public Fleet setFleet(List<Car> cars) { 
     .... 
     Optional<Vehicle> vehicle = domainService.findObjectByID(/*Some number*/); 
     .... 
    } 
} 

public class DomainService { 
    Optional<Vehicle> findObjectByID(long id) { 
     //implementation 
    } 
} 

车辆类汽车延伸。我的问题是每次findObjectByID被称为vehicle对象为空。这是有道理的,因为汽车对象被初始化为一个空列表,并且mockito when函数使用它作为返回列表,而不是在测试函数中生成的填充列表。我也得到这个运行时错误:

java.lang.ClassCastException: com.jer.test.model.Car cannot be cast to com.google.common.base.Optional 

但我改变了我的代码,并尝试了这种方式,以及:

@Before 
public void setUp() throws Exception { 
} 

@Test 
public void testVin() { 
    cars = helper.generateCars(5, /*random number*/); 
    Mockito.when(service.findObjectByID(any())).thenAnswer(AdditionalAnswers.returnsElementsOf(cars)); 
    Fleet result = foo.setFleet(Arrays.asList(helper.makeCars(3)); 
    assertEquals(/*list of numbers*/, result.getCars().getVINs()); 
} 

vehicle对象仍然为空。我不知道为什么。我出错的地方?

重新尝试1:我已经试过,没有运气以下:

@Before 
public void setUp() throws Exception { 
    MockitoAnnotations.initMocks(this);  
    foo = new Foo(); 
    helper = new TestHelper();   
} 

@Test 
public void testVin() { 
    cars = helper.generateCars(5, /*random number*/); 
    Mockito.when(service.findObjectByID(any())).then(new ReturnsElementsOf(bFIs)); 
    Fleet result = foo.setFleet(Arrays.asList(helper.makeCars(3)); 
    assertEquals(/*list of numbers*/, result.getCars().getVINs()); 
} 

重新尝试2:我已经试过了一些运气以下:

@Before 
public void setUp() throws Exception { 
    MockitoAnnotations.initMocks(this);  
    foo = new Foo(); 
    helper = new TestHelper(); 
    cars = new ArrayList<Car>(); 
    cars.add(new Car(1, 2)); 
    Mockito.when(service.findObjectByID(any())).thenAnswer(AdditionalAnswers.returnsElementsOf(cars)); 
} 

@Test 
public void testVin() { 
    cars = helper.generateCars(5, /*random number*/); 
    Fleet result = foo.setFleet(Arrays.asList(helper.makeCars(3)); 
    assertEquals(/*list of numbers*/, result.getCars().getVINs()); 
} 

而这似乎工作。返回的车辆对象是在setUp类中制作的汽车对象,但这并不是我想要的,因为我希望返回来自列表或不同的汽车对象。

重新尝试3:我试过弗洛里安Schaetz的建议,但我还是当findObjectByID被称为得到空返回:

@Before 
public void setUp() throws Exception { 
    MockitoAnnotations.initMocks(this);  
    foo = new Foo(); 
    helper = new TestHelper(); 

} 

@Test 
public void testVin() { 
    cars = helper.generateCars(5, /*random number*/); 
    for(Car car : cars) { 
     Mockito.when(service.findObjectByID(any())).thenReturn(Optional.of(car)); 
    } 
    Fleet result = foo.setFleet(Arrays.asList(helper.makeCars(3)); 
    assertEquals(/*list of numbers*/, result.getCars().getVINs()); 
} 

回答

2

这其实很简单,为sequentiel调用返回不同的东西。 ..

Mockito.when(<some mock invocation>).thenReturn(a).thenReturn(b).thenReturn(c); 

这将返回a的第一次调用,b第二和c所有OTH随之而来的。

如果你不知道有多少,你既可以使用一个Answer像你试过(很简单),但很可能也把它包这样的...

OngoingStubbing<T> stubbing = Mockito.when (<something>); 
for(Object obj : array) { 
stubbing = stubbing.then(obj); 
} 

。另一方面,我真的不明白为什么你需要编写一个UnitTest,你不知道什么是返回值......如果你问我,那么有一些代码味道。

随机测试可能对某些事情来说是一个好主意,但我不会真的用它作为残段。

无论如何,你为什么要用Mockito.when(service.findObjectByID(any()))?这不是你问题的根源吗?如果你不得不制造随机汽车(虽然我怀疑它),但它会很容易写...

List<Car> cars = helper.generateCars(5, /*random number*/); 
for(Car car : cars) { 
    Mockito.when(service.findObjectByID(car.getId())).thenReturn(car); 
} 
+0

这就是想法,但这不是我想要的。正如你在上面的代码中看到的,我试图从数组中返回对象。我不知道这个数组有多大,因为测试函数设置了'generateCars'方法。 – Richard

+0

为什么不简单编写一个调用前一个结果的thenReturn方法的方法?我会编辑答案... –

+0

所以上面的studding代码将进入设置功能?在持续发展中,T会是什么?汽车? – Richard