2

I have a class which does the following:

public class Transformer {

    public void transform(final Car car) throws IOException {
        switch (car.getType()) {
            case OFFROAD:
                OffroadCar offroadCar = new OffroadTransformer().transform(car);

                // do something with offorad car

                break;
            ...
        }
    }
}

I have a test class:

public class TransformerTest {

    @InjectMocks
    private Transformer transformer;

    @Mock
    private OffroadTransformer offroadTransformer;

    @BeforeEach
    public void setup()
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testTransform() throws IOException {
        final Car car = new Car(OFFROAD);

        when(offroadTransformer.transform(any(Car.class))).thenReturn(new OffroadCar());

        transformer.transform(car);

        // make some verifictations
    }
}

My problem now is that the when is not working. The real offroadTransformer.transform is called instead of the mock. So my assumption is that the mock is not working because the OffroadTransformer is no member of the class Transformer and the instance is created inline.

Is that correct?

If yes: How can I anyway mock it? If no: What else could be the cause?

Mulgard
  • 9,877
  • 34
  • 129
  • 232

1 Answers1

2

The problem is that the OffroadTransformer object being used is not mocked. Your test setup is creating a mock in the transformer field, but this mock is not the one being used by the method, and that confirms your hypothesis.

The setup you're using works with classes that have mocked objects as instance fields, like this:

public class Transformer {

    //injected, initialized inline, etc.
    private OffroadTransformer transformer;

    public void transform(final Car car) throws IOException {
        switch (car.getType()) {
            case OFFROAD:
                OffroadCar offroadCar = this.transformer.transform(car);

                // do something with offorad car

                break;
            ...
        }
    }
}

Into such a class, Mockito would inject the mock and the method execution would use that mock created by Mockito.

If you do not want to use this set up, then you may want to look into something like mocking the constructor of your OffroadTransformer.

On a side note, however, it's rather common practice for factory classes such as OffroadTransformer to have no state and to be used as singletons. It's therefore more natural to follow the setup mentioned above and let Mockito handle the injection for you.

ernest_k
  • 44,416
  • 5
  • 53
  • 99