mardi 26 juillet 2016

doAnswer not called in combination with spy's doCallRealMethod for partial mock with void method

I have a class I want to test, but there are methods in there I cannot test, which I mock making my class under test a partial mock. However, I do want to modify an argument passed into this method.

I thought the following construction would do the trick, but my Answer is never invoked and neither is the RuntimeException thrown. The car has no flat tires and is not parked.

Class under test

public class CarDealer {

    public Car makeCar() {
        Car car = new Car();
        addTires(car); // should be mocked, but car should be modified

        if (car.hasFlatTires()) {
            car.park();
        }

        return car;
    }

    void addTires(Car car) {
        throw new RuntimeException("this code should never be invoked");
    }

}

Test case

public class TestCarDealer {

    @Test
    public void makeCar() {
        CarDealer partialCarDealer = mock(CarDealer.class);

        doAnswer(new Answer<Void>() {
            @Override
            public Void answer(InvocationOnMock invocation) {
                ((Car) invocation.getArguments()[0]).addFlatTire();
                return null; // void method, so return null
            }
        }).when(partialCarDealer).addTires(isA(Car.class));

        doCallRealMethod().when(partialCarDealer).makeCar();

        Car car = partialCarDealer.makeCar();

        assertThat(car.isParked()).isTrue();
    }

}

Can it be done without refactoring CarDealer?

Aucun commentaire:

Enregistrer un commentaire