我有一门课,做以下事情:

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;
            ...
        }
    }
}

我有一个测试课:
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
    }
}

我现在的问题是when无法正常工作。真正的offroadTransformer.transform被调用而不是模拟。因此,我的假设是该模拟无法正常工作,因为OffroadTransformer不是Transformer类的成员,并且实例是内联创建的。

那是对的吗?

如果是,我该如何模拟呢?
如果不是:还有其他原因吗?

最佳答案

问题在于所使用的OffroadTransformer对象没有被模拟。您的测试设置正在transformer字段中创建一个模拟,但是该模拟不是该方法正在使用的模拟,它证实了您的假设。

您使用的设置适用于将模拟对象作为实例字段的类,如下所示:

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;
            ...
        }
    }
}

在这样的类中,Mockito将注入模拟,并且方法执行将使用Mockito创建的模拟。

如果您不想使用此设置,则可能需要研究OffroadTransformermocking the constructor之类的内容。

顺便说一句,对于工厂类(例如OffroadTransformer),它没有状态并用作单例是相当普遍的做法。因此,遵循上述设置并让Mockito为您处理注射更为自然。

10-07 15:28