unit-testing - Mockito 可以检测模拟使用和字段分配吗?

标签 unit-testing mocking mockito

这个用例可能最好通过测试来解释:

@Test
public void testZeroInteraction() {
    Pika pika = new Pika();
    Trainer trainer=mock(Trainer.class);

    pika.doNothing3(trainer);
    verifyZeroInteractions(trainer);
}

这是我在 Pika 类中的 doNothing3() 方法:

void doNothing3(Trainer trainerIn){
    trainer=trainerIn;
    trainerIn.name="Ash";
}

在这种情况下,verifyZeroInteractions() 不会报错并且测试通过。

Mockito 能否像上面的 doNothing3 方法那样检测赋值?

如果可以,可以使用什么Mockito方法?

最佳答案

OO 是关于行为,而不是状态

在 Mockito 的第一段右边 documentation阅读:

Let's verify some behaviour! ...

从这个意义上说;当 Mockito 谈论交互时,它们(或据我所知的任何其他模拟框架)的意思是:方法调用。

换句话说:mocked 对象对它正在模拟的类的字段一无所知

所以,您基本上可以执行以下操作:

  1. 保持当前的 testZeroInteraction() 测试(以证明没有方法被调用)
  2. 添加第二个测试,以检查真实输入对象是否未更改

喜欢:

@Test
public void testFieldUpdates() {
  Pika pika = new Pika();
  Trainer orig = new Trainer();  
  Trainer copy = new Trainer(orig);
  pika.doNothing3(copy);
  assertThat(orig, is(copy));

这个测试“意味着”什么:创建一个训练对象,然后创建它的一个副本。将第一个对象传递给您的方法;然后检查该对象是否仍然等于副本。

当然——这需要你有某种“复制构造函数”;以及 equals() 的合理实现。

最后:您实际上应该从后退开始。我的第一句话是:“面向对象是关于行为,而不是状态”。翻译成:让 Trainer 类具有公共(public)可写 字段的想法是一种设计味道。你不应该那样做。您无需创建对象、传递它们并让其他代码直接写入字段。您对其他对象调用方法,而不是操纵它们的状态。

换句话说:您的方法违反了一整套重要的 OO 原则。因此,Mockito 不支持您正在做的事情。因为没有人应该做您正在做的事情。因此,如前所述:真正的答案是修复损坏的设计。

关于unit-testing - Mockito 可以检测模拟使用和字段分配吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44752996/

相关文章:

java - 我是否需要创建工厂的测试版本以进行单元测试?

ruby - 模拟 ruby​​ 类的初始化方法?

java - Mockito.any() 匹配泛型类型 T 的任何实例

java - Mockito 使用参数模拟新实例调用

java - 使用mockito模拟控制台

java - 单元测试包含其他类的实例,而不仅仅是模拟

c# - 适用于 Windows 7 的 Microsoft Windows SDK 是否包含用于 MS 单元测试的库?

Angular 2测试: calling function directly cannot change the component object itself

python - pytest-mock assert_called_with 类函数失败

c# - 使用 TypeMock 模拟 Autofac 的 "Resolve"扩展方法