使用 when() 在 Mockito 中使用 ArgumentMatchers 时遇到问题

Trouble using ArgumentMatchers in Mockito using when()

我正在用 Mockito 编写一些单元测试,我遇到以下情况:

AmazonS3 mockedS3 = Mockito.mock( AmazonS3.class )

Bucket mockBucket = Mockito.mock( Bucket.class )
Mockito.when( mockBucket.getName() ).thenReturn("bucket-1-pub")

Mockito.when(mockedS3.doesBucketExistV2("bucket-1-pub")).thenReturn(false)

// here I'm setting up a mock that accepts any CreateBucketRequest
Mockito.when( mockedS3.createBucket(any(CreateBucketRequest.class)) )
    .thenReturn( mockBucket )

// execute the code under test
String result = doSomething()

// this is the line of the error where it doesn't see a call to createBucket 
// for any CreateBucketRequest
Mockito.verify( mockedS3 ).createBucket( any(CreateBucketRequest.class) )

这是我得到的错误:

Wanted but not invoked:
amazonS3.createBucket(
  <any com.amazonaws.services.s3.model.CreateBucketRequest>
);
-> at com.amazonaws.services.s3.AmazonS3$createBucket.call(Unknown Source)

However, there were exactly 2 interactions with this mock:
amazonS3.doesBucketExistV2("bucket-1-pub");
-> at com.fuseanalytics.archiver.model.dao.AmazonFileDao.checkBucket(AmazonFileDao.java:142)

amazonS3.createBucket(
  com.amazonaws.services.s3.model.CreateBucketRequest@255e5e2e
);
-> at com.fuseanalytics.archiver.model.dao.AmazonFileDao.checkBucket(AmazonFileDao.java:147)

Wanted but not invoked:
amazonS3.createBucket(
  <any com.amazonaws.services.s3.model.CreateBucketRequest>
);
-> at com.amazonaws.services.s3.AmazonS3$createBucket.call(Unknown Source)

However, there were exactly 2 interactions with this mock:
amazonS3.doesBucketExistV2("bucket-1-pub");
-> at com.fuseanalytics.archiver.model.dao.AmazonFileDao.checkBucket(AmazonFileDao.java:142)

amazonS3.createBucket(
  com.amazonaws.services.s3.model.CreateBucketRequest@255e5e2e
);
-> at com.fuseanalytics.archiver.model.dao.AmazonFileDao.checkBucket(AmazonFileDao.java:147)

因此,通过跟踪调用,我的 amazonS3.createBucket() 调用是使用 CreateBucketRequest 调用的,而不是 return 我配置的 mockBucket。它只是 returns null,然后当我验证它被调用时,调用不符合验证和 blamo 异常城市的条件。

更新:我尝试过移动 when() 调用,使它们与代码中调用方法的顺序保持一致。没用。 (我很高兴这没有用,因为那会有多糟糕?!黑盒测试就这么多吧?)我还尝试删除 verify()createBucket() 的调用。这只是导致下一个验证(未显示)爆炸,因为 createBucket() 仍然没有 return 我配置的内容。

我看不出这是怎么回事,所以我需要一些帮助来找出我的错误。

好的,所以我遗漏了一个重要的细节,我向评论的人道歉。我正在用 Groovy 编写我的测试。事实证明这是 Groovy 的错。我开始怀疑 Groovy 正在将它的 Groovy 方法添加到对象中,这可能会使它们在 Mockito 中看起来不一样。所以虽然它说它与 createBucket(CreateBucketRequest) 有交互。当使用 any() 匹配器时,它没有将 CreateBucketRequest 和 CreateBucketRequest + Groovy 默认方法识别为相同的东西。

现在,为什么会发生这种情况是 Mockito 开发人员要弄清楚的。我想我应该直接使用 Spock 而不是 junit,但那是以后的事了。感谢您的帮助。