【问题标题】:How to mock object that's created by a class builder?如何模拟由类构建器创建的对象?
【发布时间】:2019-07-31 04:41:14
【问题描述】:

在我目前的一堂跑步课中:

void run() {
    Food food = new FoodBuilder(apple, peach, grape)
                    .build();
    food.eatFood();

我的 FoodBuilder 类是这样的:

public class FoodBuilder implements FoodInterface {
    private Food food = new Food();

    public FoodBuilder(Apple apple, Peach peach, Grape graph) {
        food.add(apple);
        food.add(peach);
        food.add(graph);
    }

    @Override
    public Food build() {
        return food;
    } 

我的 FoodInterface 是:

public interface FoodInterface {
    Food build();
}

现在,我不能改变这个类的结构,但是我需要模拟food,这样我可以在调用food.eatFood()时绕过我的服务中的一些权限问题,基本上我不想实际调用food.eatFood(),我想模拟food,所以我可以做doNothing().when(food.eatFood())

我正在使用 PowerMockito,我的代码是这样的:

@RunWith(PowerMockRunner.class)
@PrepareForTest({FoodBuilder.class})
public class MyTest() {
    @Test
    public void mytest() {
        Food food = Mockito.mock(Food.class);
        FoodBuilder builder = Mockito.mock(FoodBuilder.class);
        when(builder.build()).thenReturn(food);

        doNothing().when(food).eatFood(); // This doesn't work! Because the food object is not a mock, instead it is a real object
    }
}

当我运行测试时,food 对象不是我想要的模拟对象,而是正在创建的真实对象,因此我无法将 food.eatFood() 告诉 doNothing()

我错过了什么?

【问题讨论】:

  • 你的Food 应该是实现接口的东西。
  • @chrylis 旧系统,我无法更改源代码。
  • 如果您想测试run 方法,这将很难注入FoodBuilder 模拟,因为您正在使用new 运算符在本地创建FooBuilder 的新实例。

标签: java junit mocking mockito powermockito


【解决方案1】:

您可以使用 PowerMockito 的 whenNew 功能来拦截构造函数调用。

@Test
public void test() throws Exception {

    Food food = Mockito.mock(Food.class);
    Mockito.doNothing().when(food).eatFood();

    FoodBuilder builder = Mockito.mock(FoodBuilder.class); 
    Mockito.when(builder.build()).thenReturn(food);

    PowerMockito.whenNew(FoodBuilder.class)
                .withArguments(any(Apple.class),any(Peach.class),any(Grape.class))
                .thenReturn(builder);

    run();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-07
    • 1970-01-01
    • 2019-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多