JMockit: макет родительских и дочерних классов

Это немного упрощенная версия результата, которого я пытаюсь достичь, но я думаю, что это иллюстрирует проблему.

Представьте, что у меня есть следующие два класса, где один является потомком другого:

public class Vehicle {

    protected String name;

    {
        name = "Vehicle";
    }

    public String getName() {
        return name;
    }

}

public class Car extends Vehicle {

    {
        name = "Car";
    }

}

У меня также есть этот тестовый код:

public class VehiclesTest {

    @Test
    public void checkVehicles(@Mocked final Vehicle vehicleMock,
                              @Mocked final Car carMock) {
        new Expectations() {
            {
                vehicleMock.getName(); result = "mocked vehicle";

                carMock.getName(); result = "mocked car";
            }
        };

        Vehicle aVehicle = new Vehicle();
        System.out.println("Starting a " + aVehicle.getName());

        Vehicle aCar = new Car();
        System.out.println("Starting a " + aCar.getName());
    }
}

То, что я хочу видеть на выходе консоли, это:

Запуск поддельного автомобиля
Начиная издеваться над автомобилем

Тем не менее, фактический вывод выглядит так:

Начиная издеваться над автомобилем
Начиная издеваться над автомобилем

Я новичок в JMockit, так что я думаю, что знаю, почему это происходит (что связано с тем, что JMockit будет издеваться над всеми классами-предками на протяжении всей иерархии классов, исключая java.lang.Object).

Как я могу настроить свои ожидания так, чтобы я получил желаемый результат? Можно ли установить ожидания для нескольких макетов разных классов в одной и той же иерархии (т. Е. Где один является потомком другого)?

1 ответ

Решение

Следующий тест будет работать:

@Test
public void checkVehicles(@Mocked Vehicle anyCarOrVehicle) {
    new Expectations() {{
        new Vehicle().getName(); result = "mocked vehicle";
        new Car().getName(); result = "mocked car";
    }};

    assertEquals("mocked vehicle", new Vehicle().getName());
    assertEquals("mocked car", new Car().getName());
}

Конечно, API в таком случае не очевиден. Как всегда, лучше всего избегать насмешек, если можете. В частности, насмешка предназначена для эмуляции и проверки поведения, а не состояния. Так что, если вы издеваетесь над "добытчиками", это явный признак плохого подхода к тестированию.

Другие вопросы по тегам