Как предотвратить высмеивание суперкласса с помощью jmockit? - PullRequest
5 голосов
/ 20 июля 2011

Учитывая иерархию классов, которая выглядит следующим образом:

public class Vehicle {

    private String name;

    public Vehicle(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

}


public class Car extends Vehicle {

    public Car(String name) {
        super(name);
    }

    public String drive() {
        return "driving the car";
    }

    public String boardBus() {
        Bus bus = new Bus("bus to cut off");

        return bus.board();
    }

}

public class Bus extends Vehicle {

    public Bus(String name) {
        super(name);
    }

    public String board() {
        return "boarding the bus";
    }

}

Я пытаюсь проверить класс автомобиля. Однако, Автомобиль также, случается, использует Автобус. Итак, в моем тесте я пытаюсь издеваться над Bus. Мой тестовый код выглядит так:

import static org.junit.Assert.assertEquals;
import mockit.Mocked;
import mockit.NonStrictExpectations;

import org.junit.Test;

public class CarTest {

    @Test
    public void testCar() {
        final String name = "I am a car";
        final Car car = new Car(name);

        new NonStrictExpectations() {
            @Mocked Bus bus;

            {
                bus.board(); result = "test bus boarding";
            }
        };

        assertEquals("I am a car", car.getName());
    }

}

Утверждение не выполняется, потому что car.getName() возвращает ноль.

Вставляя System.out.println в конструкторы для «Автомобиль», «Автомобиль» и «Автобус», я подозреваю, что «реальное» Транспортное средство, загруженное new Car(name), позже заменяется на поддельное Транспортное средство, когда @Mocked Bus bus выполняется.

Есть ли у jmockit способ сохранить реальное Транспортное средство, которое "создается" при создании Автомобиля?

Ответы [ 2 ]

1 голос
/ 20 июля 2011

Я вижу два решения:

@Test
public void boardBus_usingInstanceSpecificMockingForNewedInstances()
{
    new Expectations() {
        @Capturing @Injectable Bus bus;

        {
            bus.board(); result = "mocked";
        }
    };

    String result = new Car("myCar").boardBus();
    assertEquals("mocked", result);
}

@Test
public void boardBus_usingPartialMocking()
{
    final Bus bus = new Bus("");
    new Expectations(bus) {{ bus.board(); result = "mocked"; }};

    String result = new Car("myCar").boardBus();
    assertEquals("mocked", result);
}
0 голосов
/ 20 июля 2011

Нет транспортного средства, «связанного» с автомобилем - автомобиль является транспортным средством. Ассоциация и наследование не одно и то же. Поэтому невозможно иметь автомобиль с «поддельным» транспортным средством - это предложение не имеет смысла, когда Car extends Vehicle.

Вы уверены, что в конструкторе Car или getName() нет (законной) ошибки? Как выглядит код для этих методов?

...