ChatGPT解决这个技术问题 Extra ChatGPT

如何使用 mockito verify() 调用两次方法来验证方法

我想通过 mockito verify 验证一个方法是否至少被调用一次。我使用了验证,它抱怨如下:

org.mockito.exceptions.verification.TooManyActualInvocations: 
Wanted 1 time:
But was 2 times. Undesired invocation:

C
Community

使用适当的验证模式:

import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

verify(mockObject, atLeast(2)).someMethod("was called at least twice");
verify(mockObject, times(3)).someMethod("was called exactly three times");

您也可以使用 Mockito.times(...) 而不是 VerificationModeFactory.times(...) 进行静态导入
import static org.mockito.Mockito.times;。通常不鼓励导入包含“内部”的包 (import static org.mockito.internal.verification.VerificationModeFactory.times;)。
还有另一种写时间的方式(1)吗?
@GlennBech You can just omit that,这是隐含的;默认的 verify(mockObject).someMethod("") 只查找 1 次交互(不多也不少)。相反,如果您希望 至少一次 调用该方法,则可以使用 atLeastOnce() 说明符。
@Roger 我同意你的看法,对于像我这样的 TDD 初学者来说,静态导入让我对记住方法或正在使用哪个框架(Mockito、Espresso 或只是普通的单元测试)更加困惑。
E
Egor Hans

对于科特林:

构建梯度:

testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0"

代码:

interface MyCallback {
  fun someMethod(value: String)
}

class MyTestableManager(private val callback: MyCallback){
  fun perform(){
    callback.someMethod("first")
    callback.someMethod("second")
    callback.someMethod("third")
  }
}

测试:

import com.nhaarman.mockitokotlin2.times
import com.nhaarman.mockitokotlin2.verify
import com.nhaarman.mockitokotlin2.mock
...
val callback: MyCallback = mock()
val uut = MyTestableManager(callback)
uut.perform()

val captor: KArgumentCaptor<String> = com.nhaarman.mockitokotlin2.argumentCaptor<String>()

verify(callback, times(3)).someMethod(captor.capture())

assertTrue(captor.allValues[0] == "first")
assertTrue(captor.allValues[1] == "second")
assertTrue(captor.allValues[2] == "third")

对于 Java:

龙目岛曾经简化。如果您愿意,也可以输入构造函数。

构建梯度:

testImplementation "org.mockito:mockito-core:3.6.28"

代码:

// MyCallback.java
public interface MyCallback {
  void someMethod(String value);
}
// MyTestableManager.java
public class MyTestableManager {
  private MyCallback callback;

  public MyTestableManager(MyCallback callback) {
    this.callback = callback;
  }

  public void perform(){
    callback.someMethod("first");
    callback.someMethod("second");
    callback.someMethod("third");
  }
}

测试:

import org.mockito.Mockito.times;
import org.mockito.Mockito.verify;
import org.mockito.Mock;
import org.mockito.Captor;
// whatever other imports you need
@Mock
private MyCallback callback;
@Captor
private ArgumentCaptor<String> captor;

private MyTestableManager uut = new MyTestableManager(callback);

// in your test method:
uut.perform()

verify(callback, times(3)).someMethod(captor.capture())

assertTrue(captor.getAllValues().get(0) == "first")
assertTrue(captor.getAllValues().get(1) == "second")
assertTrue(captor.getAllValues().get(2) == "third")

如果您想知道我的编辑:基于注释的模拟创建通常在 Java 中更可取,但我不确定它是否在 Mockito Kotlin 中。至于将 manager 重命名为 uut,这只是惯例——被测试的对象(被测单元)通常被命名为 uut 或 sut(不确定后者代表什么)。