【问题标题】:How can I verify a Mockito mock is called with a specific object state when that state is subsequently changed?当随后更改该状态时,如何验证使用特定对象状态调用 Mockito 模拟?
【发布时间】:2021-08-19 18:21:46
【问题描述】:

我想测试一个服务,它接受一个可变输入参数,调用另一个服务对其进行操作,然后更改输入参数的值。

public class Stateful {
    private String value;
    // This class also has constructor, getter, setter, equals, and hashCode using value
}
public class StatefulService {
    private final StatefulOperation operation;
    public StatefulService(StatefulOperation op) { this.operation = op; }

    public void execute(Stateful input) {
        operation.doOperation(input);
        input.setValue("After");
    }
}

我想添加一个Mockito 单元测试来模拟外部操作并验证预期的调用是否正在发生。我非常想在测试中包含的一件事是传递给外部服务的对象是该对象的先前版本,因为外部服务使用该值。如果在服务调用之前更改了可变值,那将是错误的,我需要进行测试以确保调用正确发生。

我不能只将预期值传递给Mockito.verify,因为它只在测试后使用已经更新的值进行检查:

@Test
public void operationIsCalledWithSpecificState() {
    StatefulOperation operation = mock(StatefulOperation.class);
    StatefulService statefulService = new StatefulService(operation);

    statefulService.execute(new Stateful("Input"));

    // Fails, since it compares against the current state of the argument
    verify(operation).doOperation(new Stateful("Input"));
}

请注意,我无法真正更改使用模式,因为它是一种数据库实体类型,在特定于框架的预保存挂钩中发生了变异。

当对象的状态在调用后发生变化时,我如何验证传递给模拟对象的状态?

【问题讨论】:

    标签: java mocking mockito


    【解决方案1】:

    一种解决方案是设置对象的存根来进行检查。这将确保在实际调用方法时进行检查,因此可以检查实际状态。

    使用多个存根:

    @Test
    public void operationIsCalledWithSpecificState() {
        StatefulOperation operation = mock(StatefulOperation.class);
        StatefulService statefulService = new StatefulService(operation);
    
        doNothing().when(operation).doOperation(new Stateful("Input"));
        doThrow(AssertionError.class).when(operation)
                .doOperation(not(eq(new Stateful("Input"))));
    
        statefulService.execute(new Stateful("Input"));
        Mockito.verify(operation).doOperation(any());
    }
    

    使用带有Answer 的单个存根:

    @Test
    public void operationIsCalledWithSpecificState() {
        StatefulOperation operation = mock(StatefulOperation.class);
        StatefulService statefulService = new StatefulService(operation);
    
        doAnswer(answerVoid((Stateful s) -> assertEquals("Input", s.getValue())))
                .when(operation).doOperation(any());
    
        statefulService.execute(new Stateful("Input"));
        Mockito.verify(operation).doOperation(any());
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-03
      • 2016-10-06
      • 1970-01-01
      • 2020-01-04
      相关资源
      最近更新 更多