当前位置: 首页 > 知识库问答 >
问题:

如何使用Mockito更改模拟对象中的值

南宫俊喆
2023-03-14
public class Example {
  private int status;
  
  public boolean validate(ComplexObject complexObject) {
    if (status == 1) {
        //  do something...
    }
    
    if (status == -1) {
        complexObject.setErrorMessage("Some error occured!");
    }
    
    return status != -1;
  }
}
public class ComplexObject {

    //  This is a complicated object which I
    //  do not want to reproduce
    String errorMessage;

    public String getErrorMessage() {
        return errorMessage;
    }

    public void setErrorMessage(String errorMessage) {
        this.errorMessage = errorMessage;
    }
}
@ExtendWith(MockitoExtension.class)
class ExampleTest {

    @Mock
    ComplexObject complexObject;

    @Test
    public void testValidationWithErrorMessage() {
        Example example = new Example();

        assertThat(example.validate(complexObject)).isFalse();

        //  The problem: complexObject.getErrorMessage() result is null
        assertThat(complexObject.getErrorMessage()).isEqualTo("Some error message");
    }
}
complexObject.setErrorMessage("Some error occured!"); 

我最终得到null

我是否可以模拟complexObject并且在测试时仍然得到消息错误?

共有1个答案

翟嘉祥
2023-03-14

在对Mockito文档进行了一些挖掘之后,我发现了以下内容:

一旦创建,模拟将记住所有交互。然后您可以有选择地验证您感兴趣的任何交互。

默认情况下,对于返回值的所有方法,模拟将返回null、基元/基元包装值或空集合(视情况而定)。例如,对于int/integer为0,对于boolean/boolean为false。

如果您想模拟一个简单的对象,这就可以了。但如果您想检查对象内部的内容,这将变得复杂。这就是为什么我们有capture

Mockito以自然java风格验证参数值:通过使用equals()方法。这也是推荐的匹配参数的方法,因为它使测试变得简单干净。但在某些情况下,在实际验证之后对某些参数进行断言是有帮助的。

Mockito捕获器文档

@ExtendWith(MockitoExtension.class)
class ExampleTest {

    @Mock
    ComplexObject complexObject;

    @Captor private ArgumentCaptor<String> complexObjectArgumentCaptor;

    @Test
    public void testValidationWithErrorMessage() {
        Example example = new Example();

        assertThat(example.validate(complexObject)).isFalse();

        verify(complexObject).setErrorMessage(complexObjectArgumentCaptor.capture());
        var validationResult = complexObjectArgumentCaptor.getValue();
        assertThat(validationResult).isEqualTo("Some error occured!");
    }
}
 类似资料:
  • 问题内容: 当我创建一个说类Employee的模拟对象时。它不调用Employee对象的构造函数。我知道Mockito在内部使用CGLIb和反射,创建了一个代理类,将该类扩展为模拟。如果未调用employee的构造函数,那么如何创建employee类的模拟实例? 问题答案: Mockito使用CGLib生成类对象。但是,要实例化此类对象,它使用Objenesis http://objenesis.

  • org.mockito.exceptions.misusing.invaliduseofmatchersexception:在此处检测到错误的参数匹配器:->at service.activity.service.activitesServiceTest.setup(activitesServiceTest.java:45) 不能在验证或短截之外使用参数匹配器。参数匹配器的正确用法示例:when(

  • 有许多方法可以使用mockito初始化模拟对象。其中什么是最好的方法? 1. 建议我有没有比这些更好的方法...

  • 我的测试存根是 我在这里做错了什么?

  • 我尝试测试一个发送jms消息的类,但无法模拟JmsTemplate JmsProducer.class: JmsProducerTest。类别: 当我运行这个测试用例时,它给了我:java。lang.IllegalArgumentException:对象不是声明类的实例 你对这个问题有什么想法吗?

  • 问题内容: 我有一个使用当前时间进行一些计算的函数。我想使用模仿器模拟它。 我要测试的课程示例: 我想要类似的东西: 可以嘲笑吗?我不想更改“已测试”的代码以进行测试。 问题答案: 正确的做法是重组代码,使其更具可测试性,如下所示。重组代码以消除对Date的直接依赖关系将使您可以为正常运行时和测试运行时注入不同的实现: