我试图使用mockito的when
.... then
函数。我想知道是否可以为当时部分列出一个列表,但是它要遍历列表并返回另一个对象。所以,如果我有一个包含3个对象的列表:A,B,C
我希望能够遍历列表并返回列表中的下一个对象。因此,如果when内部的方法被调用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
对象为空。这是有道理的,因为cars对象被初始化为空列表,而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:我已经尝试了Florian Schaetz的建议,但是当findObjectByID
被调用时,我仍然会返回null:
@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());
}
答案 0 :(得分:2)
为sequentiel调用返回不同的东西实际上非常简单......
Mockito.when( <some mock invocation>).thenReturn( a ).thenReturn( b).thenReturn( c );
这将为第一次调用返回a
,为第二次调用返回b
,为后面的所有其他人返回c
。
如果你不知道有多少,你可以使用Answer
就像你试过的那样(很简单),但也可以像这样包装......
OngoingStubbing<T> stubbing = Mockito.when ( <something> );
for(Object obj : array) {
stubbing = stubbing.then( obj );
}
另一方面,我真的不明白为什么你需要写一个你不知道返回值是什么的UnitTest ......如果你问我,那就有一些代码味道。< / p>
对某些事情进行随机测试可能是一个好主意,但老实说,我不会用它来存根。
无论如何,为什么要使用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);
}