【问题标题】:JMockit: Mock both parent and child classesJMockit:模拟父类和子类
【发布时间】:2015-09-03 15:02:25
【问题描述】:

这是我试图实现的结果的略微简化版本,但我认为它说明了问题。

假设我有以下两个类,其中一个是另一个的后代:

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)。

如何设置我的期望,以便获得我想要的结果?是否可以对同一层次结构中不同类的多个模拟设置期望(即其中一个是另一个的后代)?

【问题讨论】:

    标签: java mocking jmockit


    【解决方案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 并不明显。一如既往,最好的办法是尽可能避免嘲弄。特别是,模拟旨在用于模拟和验证行为,而不是状态。所以,如果你在嘲笑“getter”,那就是糟糕的测试方法的强烈迹象。

    【讨论】:

    • 非常感谢!这完美无缺。在实践中,我不会嘲笑“吸气剂”——我只是用它们来证明这种情况下的期望实际上是按“预期”触发的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-24
    • 1970-01-01
    相关资源
    最近更新 更多