Java JUnit Mockito当…然后从对象数组

Java JUnit Mockito当…然后从对象数组,java,arrays,junit,mockito,Java,Arrays,Junit,Mockito,我正在尝试使用mockito的when…then函数。我想知道是否可以为then部分放入一个列表,但它可以遍历列表并返回一个不同的对象。如果我有一个包含3个对象的列表:a,B,C 我希望能够遍历列表并返回列表中的下一个对象。因此,如果when中的方法被调用3次,第一次将返回A,第二次返回B,第三次返回C。下面是我当前的代码: public class fooTest { private Foo foo; private List<Car> cars; pri

我正在尝试使用mockito的
when
then
函数。我想知道是否可以为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
    }
}
但我已经更改了代码,并尝试了以下方法:

@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());
}
但是
车辆
对象仍然为空。我不知道为什么。有什么地方我做错了吗

重新尝试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());
}

为sequentiel调用返回不同的内容实际上非常简单

Mockito.when( <some mock invocation>).thenReturn( a ).thenReturn( b).thenReturn( c );
另一方面,我真的不明白为什么你需要写一个单元测试,你不知道返回值是什么。。。如果你问我的话,这里面有某种代码的味道

对于某些事情来说,随机测试可能是一个好主意,但老实说,我不会将其用于存根

无论如何,为什么要使用
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);
}
List cars=helper.generateCars(5,/*随机数*/);
用于(汽车:汽车){
Mockito.when(service.findObjectByID(car.getId())。然后return(car);
}

实际上,为sequentiel调用返回不同的内容非常简单

Mockito.when( <some mock invocation>).thenReturn( a ).thenReturn( b).thenReturn( c );
另一方面,我真的不明白为什么你需要写一个单元测试,你不知道返回值是什么。。。如果你问我的话,这里面有某种代码的味道

对于某些事情来说,随机测试可能是一个好主意,但老实说,我不会将其用于存根

无论如何,为什么要使用
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);
}
List cars=helper.generateCars(5,/*随机数*/);
用于(汽车:汽车){
Mockito.when(service.findObjectByID(car.getId())。然后return(car);
}

没错,这是我的想法,但这不是我想要的。正如您在上面的代码中看到的,我试图从数组返回对象。我不知道数组有多大,因为测试函数在
generateCars
方法中设置了这些函数。为什么不简单地编写一个方法来调用前一个结果的thenReturn方法呢?我会编辑答案…那么上面的studing代码会进入设置功能吗?那么长筒里的T是什么呢?Car?返回值,但是一旦你在中放入了一些东西,它就会隐式存在,所以你不必写它。不,这在你的before方法中没有意义,因为那里的汽车列表是空的。在每种方法中都必须这样做。但老实说,我仍然不认为有必要在那里随意多开几辆车。我也不认为有必要一辆车一辆车地归还他们。为什么不能给出显式ID而不是
any()
,然后通过when(foo(someId))返回它们。然后返回(someCar);您甚至可以更轻松地将其包装到for循环中。使用更改编辑帖子。我仍然无法从列表中归还汽车。然而,我只想澄清,正在生成的汽车数量不是随机的。如果您看到generateCars的方法签名,那么您将看到第一个参数是测试函数作为已知数字通过的汽车数量。对,这就是想法,但这不是我想要的。正如您在上面的代码中看到的,我试图从数组返回对象。我不知道数组有多大,因为测试函数在
generateCars
方法中设置了这些函数。为什么不简单地编写一个方法来调用前一个结果的thenReturn方法呢?我会编辑答案…那么上面的studing代码会进入设置功能吗?那么长筒里的T是什么呢?Car?返回值,但是一旦你在中放入了一些东西,它就会隐式存在,所以你不必写它。不,这在你的before方法中没有意义,因为那里的汽车列表是空的。在每种方法中都必须这样做。但老实说,我仍然不认为有必要在那里随意多开几辆车。我也不认为有必要一辆车一辆车地归还他们。为什么不能给出显式ID而不是
any()
,然后通过when(foo(someId))返回它们。然后返回(someCar);您甚至可以更轻松地将其包装到for循环中。使用更改编辑帖子。我仍然无法从列表中归还汽车。然而,我只想澄清,正在生成的汽车数量不是随机的。如果您看到generateCars的方法签名,那么您将看到第一个参数是测试函数作为已知数字通过的汽车数量。
List<Car> cars = helper.generateCars(5, /*random number*/);
for(Car car : cars) {
    Mockito.when(service.findObjectByID(car.getId())).thenReturn(car);
}