Java 如何防止超级类被jmockit模仿?

Java 如何防止超级类被jmockit模仿?,java,jmockit,Java,Jmockit,给定如下所示的类层次结构: 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

给定如下所示的类层次结构:

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

}
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());
    }

}
我想试一下汽车等级。然而,汽车也碰巧使用公共汽车。所以,在我的测试中,我试图模拟巴士。我的测试代码如下所示:

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

}
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()
返回null

通过在Vehicle、Car和Bus的构造函数中插入
System.out.println
,我怀疑由
新车(名称)
加载的“真实”车辆后来在执行
@mocked Bus
时被模拟车辆替换

jmockit是否有办法保存在汽车制造时“实例化”的真实汽车?

没有与汽车“关联”的汽车-汽车是一辆汽车。关联和继承是不同的。因此,不可能有一辆带有“模拟”车辆的汽车-当
汽车扩展车辆时,这句话毫无意义

您确定汽车的构造或
getName()
中没有(合法)错误吗?这些方法的代码是什么样子的?

我看到两种解决方案:

@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);
}

如果您从单元测试中删除
新的非严格预期(){@Mocked…
内容,仅仅测试汽车构造和
getName()
?测试没有任何模拟通过吗?这里有些东西不符合要求。是的,如果我注释掉
新的非严格预期(){…},测试通过
。附录:我对jmockit的理解是它依赖于类而不是对象,它会自动模拟类的父类,直到(但不包括)java.lang.Object。因此,当它在类上看到
@mock
时,它会模拟该类及其父类。我希望找到的是如何隔离它行为仅适用于被模拟的特定类,以免影响其在层次结构中的兄弟类。它们都有效。我决定使用
@capture
技术。感谢您的帮助!